package com.erlinyou.im.web.controller.chat;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.erlinyou.im.common.util.PinyinUtils;
import com.erlinyou.im.common.util.StringUtil;
import com.erlinyou.im.common.uuid.UUIDGenerator;
import com.erlinyou.im.model.chat.ChatCurrwin;
import com.erlinyou.im.model.chat.ChatMessage;
import com.erlinyou.im.model.chat.ChatMessageDel;
import com.erlinyou.im.model.chat.ChatSession;
import com.erlinyou.im.model.goodfirend.Goodfirend;
import com.erlinyou.im.model.group.Group;
import com.erlinyou.im.model.group.Groupmembers;
import com.erlinyou.im.model.notified.ChatNotified;
import com.erlinyou.im.model.offline.OfflineMessage;
import com.erlinyou.im.model.offline.OfflineMessageKey;
import com.erlinyou.im.service.chat.IChatCurrwinService;
import com.erlinyou.im.service.chat.IChatMessageDelService;
import com.erlinyou.im.service.chat.IChatMessageService;
import com.erlinyou.im.service.chat.IChatSessionService;
import com.erlinyou.im.service.goodfirend.GoodfirendService;
import com.erlinyou.im.service.group.GroupService;
import com.erlinyou.im.service.group.IGroupMemService;
import com.erlinyou.im.service.offline.IOfflineMessageService;
import com.erlinyou.im.web.aspect.SystemLog;
import com.erlinyou.im.web.controller.base.Constants;
import com.erlinyou.im.web.controller.base.DownloadImages;
import com.erlinyou.im.web.controller.base.ImgUtils;
import com.erlinyou.im.web.controller.base.JsonUtil;
import com.erlinyou.im.web.controller.base.QrCodeCreateUtil;
import com.erlinyou.im.web.controller.base.ResultCode;
import com.erlinyou.im.web.controller.base.ResultJson;
import com.erlinyou.im.web.controller.base.ResultJsonBuild;
import com.erlinyou.im.web.controller.base.SearchVo;
import com.erlinyou.im.web.controller.base.SiteUtil;
import com.erlinyou.im.web.controller.base.WebSearchVo;
import com.erlinyou.im.web.controller.base.message.CallCenterType;
import com.erlinyou.im.web.controller.base.message.CallRoleType;
import com.erlinyou.im.web.controller.base.message.ChatType;
import com.erlinyou.im.web.controller.base.message.MessageType;
import com.erlinyou.im.web.controller.notice.ChatNotifiedService;
import com.erlinyou.im.web.controller.push.HUAWEIPushUtils;
import com.erlinyou.im.web.controller.push.PushMsgAPNS4j;
import com.erlinyou.im.web.vo.ChatMessageVo;
import com.erlinyou.im.web.vo.ChatMessageVoipVo;
import com.erlinyou.im.web.vo.GetCallIdByPOIVo;
import com.erlinyou.im.web.vo.GetIdByPOIVo;
import com.erlinyou.im.web.vo.PushMessage;
import com.erlinyou.im.web.vo.PushMessage.PushMessageType;
import com.erlinyou.im.web.vo.chat.ChatContactsVo;
import com.erlinyou.im.web.vo.chat.ChatSessionVo;
import com.erlinyou.im.web.vo.chat.GroupMemVo;
import com.erlinyou.im.web.vo.chat.GroupMemerVo;
import com.erlinyou.im.web.vo.chat.GroupVo;
import com.erlinyou.im.web.vo.chat.MessageResponseVo;
import com.erlinyou.im.web.vo.notice.ChatNotifiedVo;
import com.erlinyou.im.web.vo.user.UserInfoVo;
import com.erlinyou.im.web.wshandler.LocalWebSocketSession;
import com.erlinyou.im.web.wshandler.WSSManager;
import com.erlinyou.travel.model.user.TUser;
import com.erlinyou.travel.service.user.IUserService;
import com.erlinyou.travel.web.controller.user.S3Util;
import com.google.zxing.WriterException;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 用户相关
 * 
 * 
 * 
 * @author xujie
 *
 */

@Api(tags = { "Chat" })
@Controller
@RequestMapping(value = "/im")
@CrossOrigin(exposedHeaders={"xAuthToken"})
public class ChatMessageController {
	private static Logger logger = LoggerFactory.getLogger(ChatMessageController.class);
	@Resource
	private IChatMessageService chatMessageService;
	@Resource
	private IOfflineMessageService offlineMessageService;
	@Resource
	private IChatMessageDelService delMsgservice;
	@Resource
	private IChatSessionService chatSessionService;
	@Resource
	private IGroupMemService groupMemService;
/*	@Resource
	private OfrosterService ofrosterService;*/
	@Resource
	private GroupService groupservice;
	@Resource
	private IUserService userService;
	@Resource
	private IChatCurrwinService chatCurrwinService;
	@Resource
	private ChatNotifiedService chatNotifiedService;
	@Resource
	private GoodfirendService goodfirendService;

//	private final static String twoCodeUrl = "http://im.jingcailvtu.org:6963/im/codeloginMessage?msgId=";
	private final static String twoCodeUrl = "https://im.jingcailvtu.org:7453/im/codeloginMessage?msgId=";
//	private final static String twoCodeUrl = "http://192.168.16.112:7086/im-web/im/codeloginMessage?msgId=";
//	private final static String twoCodeUrl = "http://192.168.16.223:8080/im-web/im/codeloginMessage?msgId=";
	
	public final static String sharelink = "http://www.erlinyou.com/mobile/appdownload.html?boobuz=";
	public final static String sharelink_google = "http://www.erlinyou.com/mobile/worldshare.html?boobuz=";
	
	public static final String DEFAULT_BUCKET = "file.jingcailvtu.org";
	public static final String DEFAULT_FOLDER = "userinfo";
	public static final String DEFAULT_GROUP_FOLDER = "groupinfo";

	public static final String S3_HOST ="https://s3.cn-north-1.amazonaws.com.cn/";
	
	
	
	/**
	 * 客户端接收到消息,发送给服务端
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "消息回执", notes = "接收客户端消息回执,删除离线记录")
	@ApiImplicitParams({ @ApiImplicitParam(name = "msgid", required = true, value = "消息ID", dataType="String", paramType = "query") })
	@PostMapping(value = "/receiptMessage")
	@ResponseBody
	public ResultJson<Object> receiptMessage(HttpServletRequest request, @RequestParam(required = true) String msgid) {
		logger.info("删除离线记录ID" + msgid);
		Long userId = SiteUtil.getCurrUserId(request);
		OfflineMessageKey offlineMessageKey = new OfflineMessageKey();
		offlineMessageKey.setMsgid(msgid);
		offlineMessageKey.setUserid(userId);
		Optional<OfflineMessage> offlineMessage = offlineMessageService.findById(offlineMessageKey);
		if(!offlineMessage.isPresent()){
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);	
		}
		offlineMessageService.deleteById(offlineMessageKey);
		return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
	}
	/**
	 * 发送添加好友请求
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 * @throws IOException 
	 */
	@ApiOperation(value = "发送添加好友请求", notes = "发送添加好友请求")
	@ApiImplicitParams({ @ApiImplicitParam(name = "jid", required = true, value = "对方ID", dataType="String", paramType = "query"),
		@ApiImplicitParam(name = "isReply", required = true, value = "是否为拒绝添加好友消息，1为添加好友请求，2为拒绝添加，3为同意添加", dataType="int",example="0", paramType = "query")})
	@PostMapping(value = "/sendaddGoodFriend")
	@ResponseBody
	public ResultJson<Object> sendaddGoodFriend(HttpServletRequest request, @RequestParam(required = true) Long jid,
			@RequestParam(required = true) int isReply) throws IOException {
		//拿到自己的用户表信息
		TUser tuser = SiteUtil.getCurrUser(request);
		Long userId = tuser.getUserid();
		//拿到对方的用户表信息
		TUser rtuser = userService.findByUserid(jid);
		if(rtuser==null) {
			return ResultJsonBuild.buildObj(ResultCode.FIREND_NON_EXISTENT);
		}
		Long rid = rtuser.getUserid();
		//拿到from好友表与to的关系(isReply=1||2取反)
		Goodfirend fgoodfirend = goodfirendService.findByUseridAndJid(userId, rid);

		//处理邀请者撤回邀请时被邀请者操作（同意或添加）引发的修改数据状态不存在问题
		if(fgoodfirend==null && isReply!=1) {
			fgoodfirend = new Goodfirend();
			fgoodfirend.setCreatetime(System.currentTimeMillis());
			fgoodfirend.setFpermission("default");
			fgoodfirend.setPermission("default");
			fgoodfirend.setJid(userId);
			fgoodfirend.setRelation(-1);
			fgoodfirend.setUserid(rid);
			fgoodfirend.setNoreadnum(0);
		}
		//拿到to好友表与from的关系(isReply=1||2取反)
		Goodfirend tgoodfirend = goodfirendService.findByUseridAndJid(rid,userId);
		
		//处理邀请者撤回邀请时被邀请者操作（同意或添加）引发的修改数据状态不存在问题
		if(tgoodfirend==null && isReply!=1) {
			tgoodfirend = new Goodfirend();
			tgoodfirend.setCreatetime(System.currentTimeMillis());
			tgoodfirend.setFpermission("default");
			tgoodfirend.setPermission("default");
			tgoodfirend.setJid(rid);
			tgoodfirend.setRelation(0);
			tgoodfirend.setUserid(userId);
			tgoodfirend.setNoreadnum(1);
		}
		
		String clientid = UUIDGenerator.nextId();
		if(isReply==1) {
			//添加好友请求 
			if(fgoodfirend!=null||tgoodfirend!=null) {
				if(fgoodfirend.getRelation()==1||fgoodfirend.getRelation()==2||tgoodfirend.getRelation()==2||tgoodfirend.getRelation()==1) {
					goodfirendService.delete(fgoodfirend);
					goodfirendService.delete(tgoodfirend);
				}else {
					return ResultJsonBuild.buildObj(ResultCode.FIREND_ADDFIREND_ERROR);
				}
			}
			logger.info("请求添加好友ID" + rid);
			ChatMessage message = new ChatMessage();
			message.setClientid(clientid);
			message.setContent("");
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.SINGLE.getCode());
			message.setFromId(userId);
			message.setGid(getGid(userId, rid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(rid);
			
		/*	if(fgoodfirend.getRelation()==3 || tgoodfirend.getRelation()==3 || fofroster!=null || tofroster!=null) {
				return ResultJsonBuild.buildObj(ResultCode.FIREND_ADDFIREND_ERROR);
			}*/
			
			ArrayList<Goodfirend> list = new ArrayList<Goodfirend>();
			Goodfirend fgoodfirend1 = new Goodfirend();
			//更新from  发送方表关系字段
			fgoodfirend1.setUserid(userId);
			fgoodfirend1.setJid(rid);
			fgoodfirend1.setRelation(-1);
			fgoodfirend1.setCreatetime(System.currentTimeMillis());
			fgoodfirend1.setNoreadnum(0);
			fgoodfirend1.setPermission("default");
			fgoodfirend1.setFpermission("default");
			//更新to  接收方表关系字段
			Goodfirend tgoodfirend1 = fgoodfirend1.copy();
		//	tgoodfirend1.setFid(Math.abs(UUID.randomUUID().getLeastSignificantBits()));
			tgoodfirend1.setRelation(0);
			tgoodfirend1.setUserid(rid);
			tgoodfirend1.setJid(userId);
			tgoodfirend1.setNoreadnum(1);
			tgoodfirend1.setPermission("default");
			tgoodfirend1.setFpermission("default");
			
			list.add(fgoodfirend1);
			list.add(tgoodfirend1);
			
			boolean b = goodfirendService.saveAll(list)!=null;
			if(!b) {
				return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
			}
			sendSingnMessage(tuser,message, MessageType.SEND_GOODFIREND, rid, false, false);
			
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else if(isReply==2) {
			
			List<Goodfirend> list = new ArrayList<Goodfirend>();
			//拒绝好友请求
			logger.info("拒绝添加好友ID" + rid);
			ChatMessage message = new ChatMessage();
			message.setClientid(clientid);
			message.setContent("");
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.SINGLE.getCode());
			message.setFromId(userId);
			message.setGid(getGid(userId, rid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(rid);
			
			//更新from  接收方表关系字段
			tgoodfirend.setRelation(2);
			tgoodfirend.setNoreadnum(1);
			//更新to  接收方表关系字段
			fgoodfirend.setRelation(1);
			fgoodfirend.setNoreadnum(0);
			
			list.add(fgoodfirend);
			list.add(tgoodfirend);
			
			boolean b = goodfirendService.saveAll(list)!=null;
			if(b) {
				sendSingnMessage(tuser,message, MessageType.NO_GOODFIREND, rid, false, false);
				return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
			}else {
				return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
			}
		}else if(isReply==3) {
			//同意好友请求
			logger.info("同意添加好友ID" + rid);
			
			UserInfoVo userInfoVo = new UserInfoVo();
			userInfoVo.setUserid(userId);
			userInfoVo.setNickName(tuser.getNickName());
			userInfoVo.setImage(tuser.getImage());
			
			ChatMessage message = new ChatMessage();
			message.setClientid(clientid);
			message.setContent(JsonUtil.ObjectToJson(userInfoVo));
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.SINGLE.getCode());
			message.setFromId(userId);
			message.setGid(getGid(userId, rid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(rid);
			
			ArrayList<Goodfirend> list = new ArrayList<Goodfirend>();
			
			//更新to  发送方表关系字段
			fgoodfirend.setRelation(3);
			fgoodfirend.setNoreadnum(0);
			//更新from  接收方表关系字段
			tgoodfirend.setRelation(3);
			tgoodfirend.setNoreadnum(1);
			
			list.add(fgoodfirend);
			list.add(tgoodfirend);
			
			boolean b = goodfirendService.saveAll(list)!=null;
			if(!b) {
				return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
			}
			
			sendSingnMessage(tuser,message, MessageType.YES_GOODFIREND, rid, true, true);
			sendSingnMessage(tuser,message, MessageType.YES_GOODFIREND, userId, false, true);
			
			ResultJson<Object> resultJson = new ResultJson<Object>();
			userInfoVo.setUserid(rid);
			userInfoVo.setNickName(rtuser.getImage());
			userInfoVo.setImage(rtuser.getImage());
			return resultJson.setObj(userInfoVo);
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
	}
	/**
	 * 客户端接收到消息,发送给服务端
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "设置聊天窗口", notes = "设置聊天窗口")
	@ApiImplicitParams({ @ApiImplicitParam(name = "rid", required = true, value = "对方ID,如果切出窗口,传值0", dataType="int",example="0", paramType = "query"),
		@ApiImplicitParam(name = "ctype", required = true, value = "聊天类型", dataType="int",example="0", paramType = "query")})
	@PostMapping(value = "/setCurrWin")
	@ResponseBody
	public ResultJson<Object> setCurrWin(HttpServletRequest request, @RequestParam(required = true) long rid,
			@RequestParam(required = true) int ctype) {
		
		ChatType chatTypeEnum = ChatType.valueOf(ctype);
		if (chatTypeEnum == ChatType.UNKNOW)
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		
		Long userId = SiteUtil.getCurrUserId(request);
		if(rid <= 0){
			chatCurrwinService.deleteByUserid(userId);
		}else{
			ChatCurrwin chatCurrwin = new ChatCurrwin();
			chatCurrwin.setCtype(ctype);
			chatCurrwin.setRid(rid);
			chatCurrwin.setUserid(userId);
			
			chatCurrwinService.setCurrwinAndCleanReadNum(chatCurrwin);
			logger.info("未读数清零IDto：" + rid+"f:"+userId);
		}
		return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
	}
	/**
	 * 设置群消息免打扰
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "设置群消息免打扰", notes = "设置群消息免打扰")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "设置免打扰的群ID", dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "flag", required = true, value = "1为免打扰，2为取消免打扰", dataType="int",example="1", paramType = "query")})
	@PostMapping(value = "/setGroupNotice")
	@ResponseBody
	@CacheEvict(value="cache2",allEntries=true)
	public ResultJson<Object> setGroupNotice(HttpServletRequest request, @RequestParam(required = true) int groupid,
			@RequestParam(required = true) int flag) {
		
		
		Long userId = SiteUtil.getCurrUserId(request);
		Groupmembers groupmembers = groupMemService.findByGroupidAndUserid(groupid, userId);
		if(flag==1) {
			if(groupmembers!=null){
				groupmembers.setIsNotice(1);
			}
		}else if(flag==2){
			if(groupmembers!=null){
				groupmembers.setIsNotice(0);
			}
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		boolean b = groupMemService.save(groupmembers)!=null;
		if(b) {
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
	}
	/**
	 * 设置权限信息
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 * @throws IOException 
	 */
	@ApiOperation(value = "设置权限信息", notes = "设置权限信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "to", required = true, value = "对方id", dataType="int",example="0", paramType = "query"),
		@ApiImplicitParam(name = "permission", required = true, value = "设置权限json", dataType="String", paramType = "query")
	})
	@PostMapping(value = "/setroster")
	@ResponseBody
	@CacheEvict(value="cache2",allEntries=true)
	public ResultJson<Object> setroster(HttpServletRequest request, @RequestParam(required = true) long to,
			@RequestParam(required = true) String permission) throws IOException {
		TUser tuser = SiteUtil.getCurrUser(request);
		Long userId = tuser.getUserid();
		
		Goodfirend goodfirend = goodfirendService.findByUseridAndJidAndRelation(userId, to, 3);
		Goodfirend goodfirend1 = goodfirendService.findByUseridAndJidAndRelation(to,userId, 3);
		
		goodfirend.setFpermission(permission);
		goodfirend1.setPermission(permission);
		List<Goodfirend> list = new ArrayList<Goodfirend>();
		list.add(goodfirend);
		list.add(goodfirend1);
		boolean b = goodfirendService.saveAll(list).size()>0;
		
		if(b) {
			ChatMessage chatMessage = new ChatMessage();
			chatMessage.setCt(System.currentTimeMillis());
			chatMessage.setFromId(userId);
			chatMessage.setContent(permission);
			chatMessage.setToId(to);
			chatMessage.setId(UUIDGenerator.nextId());
			chatMessage.setCtype(ChatType.SINGLE.getCode());
			sendSingnMessage(tuser, chatMessage, MessageType.SPECIAL_ROSTER, to, false,false);
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
	}
	/**
	 * 获取权限信息
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "获取权限信息", notes = "获取权限信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "to", required = true, value = "对方id", dataType="int",example="1", paramType = "query")
	})
	@PostMapping(value = "/getroster")
	@ResponseBody
	public ResultJson<Goodfirend> getroster(HttpServletRequest request, @RequestParam(required = true) long to) {
		ResultJson<Goodfirend> resultJson = new ResultJson<Goodfirend>();
		Long userId = SiteUtil.getCurrUserId(request);
		
		Goodfirend goodfirend = goodfirendService.findByUseridAndJidAndRelation(userId, to, 3);
		
		return resultJson.setObj(goodfirend);
	}
	/**
	 * 删除好友
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 * @throws IOException 
	 */
	@ApiOperation(value = "删除好友", notes = "删除好友")
	@ApiImplicitParams({ @ApiImplicitParam(name = "rid", required = true, value = "删除好友ID", dataType="int",example="0", paramType = "query"),
		})
	@PostMapping(value = "/delGoodFriend")
	@ResponseBody
	public ResultJson<Object> delGoodFriend(HttpServletRequest request, @RequestParam(required = true) long rid) throws IOException {
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
		
		
		Goodfirend goodfirend = goodfirendService.findByUseridAndJid(userId, rid);
		int relation = goodfirend.getRelation();
//		Ofroster roster = ofrosterService.findByUsernameAndJid(userId.toString(), String.valueOf(rid));
		boolean b = false;
/*		if(roster!=null) {
			b = ofrosterService.delGoodFriend(userId, rid,getGid(userId, rid));
		}*/
		if(goodfirend!=null) {
			b = goodfirendService.delGoodFriend(userId, rid,getGid(userId, rid));
		}
		
		if(b && relation==3) {
			ChatMessage message = new ChatMessage();
			message.setClientid(UUIDGenerator.nextId());
			message.setContent("");
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.SINGLE.getCode());
			message.setFromId(userId);
			message.setGid(getGid(userId, rid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(rid);
			sendSingnMessage(currUser,message, MessageType.DEL_GOODFIREND, rid, false, false);
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else if(b){
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		
	}

	/**
	 * 消息撤回
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 * @throws IOException 
	 */
	@ApiOperation(value = "用户撤回消息", notes = "用户撤回消息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "msgid", required = true, value = "消息ID", dataType="String", paramType = "query") })
	@PostMapping(value = "/revokeMessage")
	@ResponseBody
	public ResultJson<Object> revokeMessage(HttpServletRequest request, @RequestParam(required = true) String msgid) throws IOException {
		logger.info("撤回消息ID" + msgid);
		Long userId = SiteUtil.getCurrUserId(request);
		TUser tUser = SiteUtil.getCurrUser(request);
		
		ChatMessage chatMessage = chatMessageService.findByFAndId(userId, msgid);
		if(chatMessage == null || chatMessage.getRev() == 1){
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		chatMessage.setType(MessageType.REVOKE_Message.getCode());
		chatMessage.setRev(1);//设置消息已经撤回
		
		ChatMessageVo chatMessageVo = new ChatMessageVo();
		BeanUtils.copyProperties(chatMessage, chatMessageVo);
		String chatMessageVoJson = JsonUtil.ObjectToJson(chatMessageVo);
		
		List<ChatSession> listChatSession = new ArrayList<>();
		
		//发送方
		ChatSession chatSession = new ChatSession(chatMessage.getFromId(), chatMessage.getToId(), chatMessage.getCt(),chatMessage.getCtype(), chatMessageVoJson, 0);
		listChatSession.add(chatSession);
		
		
		boolean isSingleChat = chatMessage.getGid().contains("_");//是否为单聊
		List<Long> toUserids = new ArrayList<>();// 需要推送的用户
		Long to = chatMessage.getToId();
		if(isSingleChat){
			toUserids.add(to);
		}else{
			List<Groupmembers> groupmembers = groupMemService.findByGroupid(to.intValue());
			groupmembers.forEach(item -> toUserids.add(item.getUserid()));
		}
		
		toUserids.forEach(userid -> {
			ChatSession toChatSession = chatSession.copy();
			toChatSession.setUserid(userid);
			toChatSession.setRid(chatMessage.getFromId());
			toChatSession.setNoreadnum(1);
			listChatSession.add(toChatSession);
		});
		
		chatMessageService.revokeMessage(chatMessage, listChatSession);
/*
		RevokeMessage revokeMessage = new RevokeMessage();
		revokeMessage.setMsgid(msgid);
		revokeMessage.setRid(userId);*/
		
		if(isSingleChat) {
			sendSingnMessage(tUser, chatMessage, MessageType.REVOKE_Message, to, false, false);
		}else {
		//	sendGroupMessage(chatMessage, MessageType.REVOKE_Message, toUserids, false);
			chatMessageVo.setOff(1);
			String pushContentoff = new PushMessage<>(chatMessageVo, PushMessageType.SYS).buildJson();
			List<OfflineMessage> dbOfflineMessage = new ArrayList<OfflineMessage>();
			toUserids.forEach(userid -> {
				// 存储离线消息
				OfflineMessage offlineMessage = new OfflineMessage();
				offlineMessage.setCt(chatMessage.getCt());
				offlineMessage.setContent(pushContentoff);// pushMsg
				offlineMessage.setMsgid(chatMessage.getId());
				offlineMessage.setUserid(userid);// 单聊临时处理
				dbOfflineMessage.add(offlineMessage);
			});
			toUserids.remove(userId);
			boolean b = chatMessageService.saveMessage(dbOfflineMessage);
			String pushContent = new PushMessage<>(chatMessageVo, PushMessageType.SYS).buildJson();
			if(b) {
				WSSManager.sendMessageText(toUserids, pushContent);
			}
		}
		
		/*
		toUserids.forEach(userid -> {
			SysMessageUtil.pushSysMessage(userid, chatMessageVo, offlineMessageService);//推送给在线用户消息撤回
		});
		*/
		return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
	}

	/**
	 * 删除消息ID
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "删除消息ID", notes = "删除聊天记录")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "msgid", required = true, value = "消息ID", dataType="String", paramType = "query")
	})
	@PostMapping(value = "/delMsg")
	@ResponseBody
	public ResultJson<Object> delMsg(HttpServletRequest request, @RequestParam(required = true) String msgid) {
		long millis = System.currentTimeMillis();
		Long currUserId = SiteUtil.getCurrUserId(request);
		ChatMessageDel delMsg = new ChatMessageDel();
		delMsg.setCt(millis);
		delMsg.setXid(msgid);
		delMsg.setUserid(currUserId);

		boolean zt = delMsgservice.save(delMsg) != null;

		if (zt) {
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		} else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
	}

	/**
	 * 
	 * 提供电商获取好友ID接口
	 */
	@ApiOperation(value = "提供电商获取好友ID接口", notes = "获取新联系人列表[好友ID]")
	@PostMapping(value = "/getFriendsId")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "userId", required = true, value = "消息ID", dataType="int",example="0", paramType = "query")
	})
	@ResponseBody
	public ResultJson<List<Integer>> getFriendsId(HttpServletRequest request,@RequestParam(required = true) Long userId) {
		ResultJson<List<Integer>> resultJson = new ResultJson<List<Integer>>();
		List<Integer> Jid = goodfirendService.queryUserid(userId);
		resultJson.setObj(Jid);
		return resultJson;
	}
	
	
	/**
	 * 
	 * 获取新好友列表
	 */
	@ApiOperation(value = "获取联系人列表", notes = "获取新联系人列表[好友]")
	@PostMapping(value = "/getContacts")
	@ResponseBody
	public ResultJson<List<ChatContactsVo>> getContacts(HttpServletRequest request) {
		ResultJson<List<ChatContactsVo>> resultJsonBuild = new ResultJson<List<ChatContactsVo>>();
		
		List<ChatContactsVo> allList = new ArrayList<>();
		
		Long userId = SiteUtil.getCurrUserId(request);
		
		// 查询好友id字段
		List<Goodfirend> newContactslist = goodfirendService.findByUserid(userId);
	//	List<Ofroster> contactslist = ofrosterService.findByUsernameAndSub(userId.toString(),(byte)3);
		List<Long> userIds = newContactslist.stream().map(item -> Long.valueOf(item.getJid())).collect(Collectors.toList());
		List<TUser> contactsUsers = userService.findAllById(userIds);
		Map<Long, TUser> userMap = new HashMap<>();
		contactsUsers.forEach(item->userMap.put(item.getUserid(), item));
		
		List<Group> group = groupservice.selectBygroup(userId,1);
//		List<Group> findAll = groupservice.findAllByUserid(userId);

		for (Group group2 : group) {
			ChatContactsVo chatContactsVoGroup = new ChatContactsVo();
			chatContactsVoGroup.setImage(group2.getImage());
			chatContactsVoGroup.setName(group2.getName());
			chatContactsVoGroup.setRid(Long.valueOf(group2.getId()));
			chatContactsVoGroup.setOwner(group2.getOwner());
			chatContactsVoGroup.setCtype(ChatType.GROUP.getCode());
			List<GroupMemVo> result = new ArrayList<GroupMemVo>();
			for (Groupmembers item : group2.getGroupmembers()) {
				TUser user = userService.findByUserid(item.getUserid());
				GroupMemVo GroupMemResult = new GroupMemVo();
				if(item.getUserid().equals(userId)) {
					chatContactsVoGroup.setIsNotice(item.getIsNotice());
				}
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				try {
					GroupMemResult.setUserImage(user.getImage());
				} catch (Exception e) {
					GroupMemResult.setUserImage("");
				}
				result.add(GroupMemResult);
			}
			chatContactsVoGroup.setGroupmembers(result);
			allList.add(chatContactsVoGroup);
		}
		
		List<ChatContactsVo> rosterList = newContactslist.stream().map(contacts -> {
			ChatContactsVo chatContactsVo = new ChatContactsVo();
			Long userid = Long.valueOf(contacts.getJid());
			TUser user = userMap.get(userid);
			
			chatContactsVo.setRid(userid);
			chatContactsVo.setCtype(ChatType.SINGLE.getCode());
			chatContactsVo.setName(user.getNickName());
			chatContactsVo.setImage(user.getImage());
			chatContactsVo.setRelation(contacts.getRelation());
			chatContactsVo.setPermission(contacts.getPermission());
			chatContactsVo.setFpermission(contacts.getFpermission());
			return chatContactsVo;
		}).collect(Collectors.toList());
		allList.addAll(rosterList);
		
//		Collections.sort(allList); 
	/*	Collections.sort(allList, new Comparator<ChatContactsVo>() {
			@Override  
            public int compare(ChatContactsVo o1, ChatContactsVo o2) {
				ChatContactsVo newo1 = new ChatContactsVo();
				ChatContactsVo newo2 = new ChatContactsVo();
				if(StringUtil.isEmpty(o1.getName())||StringUtil.isEmpty(o2.getName())) {
					return -1;
				}
                newo1.setName(PinyinUtils.ToPinyinAndGetFirstChar(o1.getName()));
                newo2.setName(PinyinUtils.ToPinyinAndGetFirstChar(o2.getName()));
                int i = newo1.getName().substring(0, 1).compareTo(newo2.getName().substring(0, 1));
                return i;
            }
		});*/
		List<Group> list = groupservice.findByGtype(CallCenterType.WORLD.getCode());

		for (Group group2 : list) {
			ChatContactsVo chatContactsVoGroup = new ChatContactsVo();
			chatContactsVoGroup.setImage(group2.getImage());
			chatContactsVoGroup.setName(group2.getName());
			chatContactsVoGroup.setRid(Long.valueOf(group2.getId()));
			chatContactsVoGroup.setOwner(group2.getOwner());
			chatContactsVoGroup.setCtype(ChatType.CALLCENTER.getCode());
			List<GroupMemVo> result = new ArrayList<GroupMemVo>();
			for (Groupmembers item : group2.getGroupmembers()) {
				TUser user = userService.findByUserid(item.getUserid());
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				GroupMemResult.setGroupid(group2.getId());
				GroupMemResult.setUserImage(user.getImage());
				result.add(GroupMemResult);
			}
			chatContactsVoGroup.setGroupmembers(result);
			chatContactsVoGroup.setCallcenterType(group2.getGtype());
			chatContactsVoGroup.setCallcenterRole(CallRoleType.NONE.getCode());
			List<Groupmembers> callCenterlist = group2.getGroupmembers();
			for (Groupmembers callCentermem : callCenterlist) {
				if(Long.valueOf(callCentermem.getUserid()).equals(userId)) {
					if(group2.getOwner().equals(userId)) {
						chatContactsVoGroup.setCallcenterRole(CallRoleType.OWNER.getCode());//枚举
					}else {
						chatContactsVoGroup.setCallcenterRole(CallRoleType.MEMBER.getCode());//枚举
					}
				}
			}
			allList.add(0, chatContactsVoGroup);
		}
		List<Group> list1 = groupservice.findCustom(userId,CallCenterType.CUSTOM.getCode());
		
		for (Group group2 : list1) {
			ChatContactsVo chatContactsVoGroup = new ChatContactsVo();
			chatContactsVoGroup.setImage(group2.getImage());
			chatContactsVoGroup.setName(group2.getName());
			chatContactsVoGroup.setRid(Long.valueOf(group2.getId()));
			chatContactsVoGroup.setOwner(group2.getOwner());
			chatContactsVoGroup.setCtype(ChatType.CALLCENTER.getCode());
			List<GroupMemVo> result = new ArrayList<GroupMemVo>();
			for (Groupmembers item : group2.getGroupmembers()) {
				TUser user = userService.findByUserid(item.getUserid());
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				GroupMemResult.setGroupid(group2.getId());
				GroupMemResult.setUserImage(user.getImage());
				result.add(GroupMemResult);
			}
			chatContactsVoGroup.setGroupmembers(result);
			chatContactsVoGroup.setCallcenterType(group2.getGtype());
			chatContactsVoGroup.setCallcenterRole(CallRoleType.NONE.getCode());
			List<Groupmembers> callCenterlist = group2.getGroupmembers();
			for (Groupmembers callCentermem : callCenterlist) {
				if(Long.valueOf(callCentermem.getUserid()).equals(userId)) {
					if(group2.getOwner().equals(userId)) {
						chatContactsVoGroup.setCallcenterRole(CallRoleType.OWNER.getCode());//枚举
					}else {
						chatContactsVoGroup.setCallcenterRole(CallRoleType.MEMBER.getCode());//枚举
					}
				}
			}
			allList.add(0, chatContactsVoGroup);
		}
		 
		return resultJsonBuild.setObj(allList);
		
	}

	/**
	 * 获取消息
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "获取消息", notes = "获取聊天记录")
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "rid", required = true, value = "对方的ID",dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "ctype", required = true, value = "聊天类型",dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "page", required = true, value = "page",dataType="int",example="0", paramType = "query"),
		@ApiImplicitParam(name = "rows", required = true, value = "rows",dataType="int",example="10", paramType = "query")
	})
	@PostMapping(value = "/getMsg")
	@ResponseBody
	public ResultJson<List<ChatMessageVo>> getMsg(HttpServletRequest request, @RequestParam(required = true) Long rid,
			@RequestParam(required = true) int ctype,
			@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int rows) {
		ChatType chatType = ChatType.valueOf(ctype);
		ResultJsonBuild<List<ChatMessageVo>> resultJsonBuild = new ResultJsonBuild<>();
		if(page > 1000 || rows>50 || page<0 || rows<1 || chatType == ChatType.UNKNOW){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		List<ChatMessageVo> result = new ArrayList<>();
		
		Long userId = SiteUtil.getCurrUserId(request);
		List<ChatMessage> msglist = null;
		if(chatType == ChatType.GROUP) {
			Groupmembers groupmembers = groupMemService.findByGroupidAndUserid(rid.intValue(), userId);
			if(groupmembers==null) {
				return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
			msglist = chatMessageService.getMsg(String.valueOf(userId), rid.toString(), groupmembers.getCt(), page, rows,ctype);
			Collections.reverse(msglist);
		}else if(chatType == ChatType.CALLCENTER) {
			int role = 50;
			List<Groupmembers> callCenterMemlist = groupMemService.findByGroupid(rid.intValue());
			for (Groupmembers callCenterMember : callCenterMemlist) {
				if(Long.valueOf(callCenterMember.getUserid()).equals(userId)) {
					role = 30;
					break;
				}
			}
			if(role==30) {
				msglist = chatMessageService.getMsg(String.valueOf(userId), rid.toString(), page, rows,ctype);
			}else {
				msglist = chatMessageService.getMsgCallCenter(userId,rid.toString(),page,rows,ctype);
			}
			Collections.reverse(msglist);
		}else{
			String gid = getGid(userId, rid);
			msglist = chatMessageService.getMsg(String.valueOf(userId), gid, page, rows,ctype);
			Collections.reverse(msglist);
		}
		result = msglist.stream().map(chatMessage -> {
			ChatMessageVo chatMessageVo = new ChatMessageVo();
			BeanUtils.copyProperties(chatMessage, chatMessageVo);
			return chatMessageVo;
//			ChatMessageVo chatMessageVo = new ChatMessageVo();
//			chatMessageVo.setClientid(contacts.getClientid());
//			chatMessageVo.setContent(contacts.getContent());
//			chatMessageVo.setCt(contacts.getCt());
//			chatMessageVo.setCtype(contacts.getCtype());
//			chatMessageVo.setF(contacts.getF());
//			chatMessageVo.setId(contacts.getId());
//			chatMessageVo.setRev(contacts.getRev());
//			chatMessageVo.setT(contacts.getT());
//			chatMessageVo.setType(contacts.getType());
//			return chatMessageVo;
		}).collect(Collectors.toList());
		return resultJsonBuild.success(result);
	}

	/**
	 * 会话框
	 * 
	 * @param request
	 * @param msgId
	 * @return
	 */
	@ApiOperation(value = "获取会话", notes = "获取会话框")
	@PostMapping(value = "/getSession")
	@ResponseBody
	public ResultJson<List<ChatSessionVo>> getSession(HttpServletRequest request) {
		long getSessionStart = System.currentTimeMillis();
		ResultJsonBuild<List<ChatSessionVo>> resultJsonBuild = new ResultJsonBuild<>();

		List<ChatSessionVo> result = new ArrayList<>();
		Long userId = SiteUtil.getCurrUserId(request);
		long timeSessionStart = System.currentTimeMillis();
		List<ChatSession> chatSessionList = chatSessionService.findByUserid(userId);
		long timeSessionEnd = System.currentTimeMillis();
		System.out.println("chatSessionList 耗时："+(timeSessionEnd-timeSessionStart));
		if (chatSessionList != null) {
			result = chatSessionList.stream().map(contacts -> {
				ChatSessionVo chatContactsVo = new ChatSessionVo();
				String nickName = null;
				String image = null;
				if(contacts.getCtype()==ChatType.SINGLE.getCode()) {
					long timeUserStart = System.currentTimeMillis();
					TUser findByUserid = userService.findByUserid(contacts.getRid());
					long timeUserEnd = System.currentTimeMillis();
					System.out.println("userServiceByUserId 耗时："+(timeUserEnd-timeUserStart));
					try {
						nickName = findByUserid.getNickName();
						image = findByUserid.getImage();
					} catch (Exception e) {
						logger.warn("getSession:WARN:"+e);
					}
				}else {
					long timeGroupStart = System.currentTimeMillis();
					Optional<Group> findById = groupservice.findById(contacts.getRid().intValue());
					long timeGroupEnd = System.currentTimeMillis();
					System.out.println("groupserviceById 耗时："+(timeGroupEnd-timeGroupStart));
					if(findById.isPresent()) {
						Group group = findById.get();
						nickName = group.getName();
						image = group.getImage();
					}
				}
				org.springframework.beans.BeanUtils.copyProperties(contacts, chatContactsVo);
				
				chatContactsVo.setNickName(nickName);
				chatContactsVo.setImage(image);
				
				return chatContactsVo;
			}).collect(Collectors.toList());
		}
		
		long getSessionEnd = System.currentTimeMillis();
		System.out.println("getSession 耗时："+(getSessionEnd-getSessionStart));
		return resultJsonBuild.success(result);
	}
	
	/**
	 * 删除用户会话
	 * @param request
	 * @param rid
	 * @return
	 */
	@ApiOperation(value = "删除会话", notes = "删除会话框")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "rid", required = true, value = "对方ID", dataType="int",example="1",paramType = "query"),
		@ApiImplicitParam(name = "ctype", required = true, value = "1单2群",dataType="int",example="1", paramType = "query") })
	@PostMapping(value = "/delSession")
	@ResponseBody
	public ResultJson<Object> delSession(HttpServletRequest request,
			@RequestParam(required = true) Long rid,
			@RequestParam(required = true) int ctype) {
		Long userId = SiteUtil.getCurrUserId(request);
		int zt = chatSessionService.deleteByUseridAndRidAndCtype(userId, rid, ctype);
		if(zt>0){
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);			
		}else{
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
	}

	/**
	 * 发送消息
	 * 
	 * @param request
	 * @param clientId
	 * @param to
	 * @param content
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "发送消息", notes = "发送聊天消息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "clientid", required = true, value = "客户端消息ID", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "to", required = true, value = "接收人", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "content", required = true, value = "消息内容", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "type", required = true, value = "消息类型", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "ctype", required = true, value = "1单2群3callcenter", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "visitorId", required = false, value = "callcenter需要传id", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "cTime", required = true, value = "客户端发送时间", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "isNotVerify", required = true, value = "true单聊不加好友验证false验证", dataType="boolean", paramType = "query")})
	@PostMapping(value = "/sendMessage")
	@ResponseBody
	public ResultJson<MessageResponseVo> sendMessage(HttpServletRequest request,@ApiIgnore HttpSession session,
			@RequestParam(required = true) String clientid, @RequestParam(required = true) String to,
			@RequestParam(required = true) String content, @RequestParam(required = true) int type,
			@RequestParam(required = true) int ctype,
			@RequestParam(required = false) String visitorId,
			@RequestParam(required = true) long cTime,
			@RequestParam(required = true) Boolean isNotVerify) throws Exception {
		ResultJsonBuild<MessageResponseVo> resultJsonBuild = new ResultJsonBuild<>();
		if(Integer.parseInt(to)==0) {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		Long userId = SiteUtil.getCurrUserId(request);
		TUser tUser = SiteUtil.getCurrUser(request);
		MessageType messageTypeEnum = MessageType.valueOf(type);
		if (messageTypeEnum == MessageType.UNKNOW)
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		ChatType chatTypeEnum = ChatType.valueOf(ctype);
		if (chatTypeEnum == ChatType.UNKNOW)
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);

		boolean msgExists = chatMessageService.existsByClientid(clientid);
		if (msgExists) {
			ChatMessage chatMessage = chatMessageService.findByClientid(clientid);
			return resultJsonBuild.success(new MessageResponseVo(chatMessage.getId(),chatMessage.getClientid(), chatMessage.getCt()));
		}

		String serverMsgId = UUIDGenerator.nextId();
//		long cTime = TimeUtil.getCurrentTime();
		long currentTimeMillis = System.currentTimeMillis();
		long currentTimeMillis1 = currentTimeMillis + 1000*60*5;
		long currentTimeMillis2 = currentTimeMillis - 1000*60*5;
		if(!(cTime<currentTimeMillis1 && cTime>currentTimeMillis2)) {
			cTime = currentTimeMillis;
		}
		
		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setType(messageTypeEnum.getCode());
		chatMessage.setCtype(chatTypeEnum.getCode());
		chatMessage.setFromId(userId);
		chatMessage.setToId(Long.valueOf(to));
		chatMessage.setContent(content);
		chatMessage.setCt(cTime);
		chatMessage.setId(serverMsgId);
		chatMessage.setClientid(clientid);
		if(ctype==ChatType.CALLCENTER.getCode()) {
			if(visitorId!=""&&visitorId!=null) {
				chatMessage.setVisitorId(Long.valueOf(visitorId));
			}
			chatMessage.setGid(to);
			
		}
		if(isNotVerify) {
			chatMessage.setGid(getGid(chatMessage.getFromId(), chatMessage.getToId()));
			sendSingnMessage(tUser, chatMessage, messageTypeEnum, chatMessage.getToId(), isNotVerify,true);
		}else {
			ResultCode resultCode = sendMessage(chatMessage, messageTypeEnum, chatTypeEnum,tUser);
			if(resultCode!=ResultCode.SUCCESS) {
				return resultJsonBuild.error(resultCode.getCode(), resultCode.getMsg());
			}
		}

		return resultJsonBuild.success(new MessageResponseVo(chatMessage.getId(),chatMessage.getClientid(), chatMessage.getCt()));
	}

	/**
	 * 发送群组消息不加验证
	 * @param chatMessage
	 * @param messageTypeEnum
	 * @param uesrIds
	 * @throws IOException
	 */
	private void sendGroupMessage(ChatMessage chatMessage, MessageType messageTypeEnum,List<Long> uesrIds,boolean isFUpChatSession,TUser user) throws IOException{
		chatMessage.setType(messageTypeEnum.getCode());

		final List<Long> toUserids = new ArrayList<>();// 需要推送的用户
		
		chatMessage.setGid(chatMessage.getToId().toString());

		if(uesrIds == null){
			List<Groupmembers> groupmembers = groupMemService.findByGroupid(chatMessage.getToId().intValue());
			groupmembers.forEach(item -> toUserids.add(item.getUserid()));
		}else{
			toUserids.addAll(uesrIds);
		}

		saveChatMessage(chatMessage, messageTypeEnum, toUserids,isFUpChatSession,user);
	}
	/**
	 * 发送单聊消息不加验证
	 * @param chatMessage
	 * @param messageTypeEnum
	 * @param uesrIds
	 * @throws IOException
	 */
	private void sendSingnMessage(TUser tuser,ChatMessage chatMessage, MessageType messageTypeEnum,long rid,boolean isFUpChatSession,boolean ispush) throws IOException{
		chatMessage.setType(messageTypeEnum.getCode());
		ChatMessageVo chatMessageVo = new ChatMessageVo();
		BeanUtils.copyProperties(chatMessage, chatMessageVo);
		chatMessageVo.setImage(tuser.getImage());
		chatMessageVo.setNickName(tuser.getNickName());
		String pushContent = null;
		if(isFUpChatSession) {
			pushContent = new PushMessage<>(chatMessageVo, PushMessageType.CHAT).buildJson();
		}else {
			pushContent = new PushMessage<>(chatMessageVo, PushMessageType.SYS).buildJson();
		}

		List<ChatSession> dbChatSession = new ArrayList<>();
		List<OfflineMessage> dbOfflineMessage = new ArrayList<>();

		ChatSession chatSession = new ChatSession();
		chatSession.setUptime(chatMessage.getCt());
		chatSession.setCtype(chatMessage.getCtype());
		chatSession.setContent(JsonUtil.ObjectToJson(chatMessageVo));
		chatSession.setUserid(chatMessage.getFromId());
		chatSession.setRid(chatMessage.getToId());
		chatSession.setNoreadnum(0);
	//	if(isFUpChatSession){//是否更新发送人的最近会话
			dbChatSession.add(chatSession);
	//	}

			// 存储离线消息
			OfflineMessage offlineMessage = new OfflineMessage();
			offlineMessage.setCt(chatMessage.getCt());
			offlineMessage.setContent(pushContent);// pushMsg
			offlineMessage.setMsgid(chatMessage.getId());
			offlineMessage.setUserid(rid);// 单聊临时处理
			dbOfflineMessage.add(offlineMessage);

			ChatSession toChatContacts = chatSession.copy();
			toChatContacts.setUserid(rid);
			toChatContacts.setRid(chatMessage.getFromId());
			toChatContacts.setNoreadnum(1);
			
			Optional<ChatCurrwin> chatCurrwin = chatCurrwinService.findById(rid);
			if(chatCurrwin.isPresent()){
				ChatCurrwin currWin = chatCurrwin.get();
				if(currWin.getCtype().equals(ChatType.SINGLE.getCode())){//单聊取fromid 
					if(currWin.getRid().equals(chatMessage.getFromId())){
						toChatContacts.setNoreadnum(0);
					}
				}else{
					if(currWin.getRid().equals(chatMessage.getToId())){
						toChatContacts.setNoreadnum(0);
					}
				}
			}
			
			dbChatSession.add(toChatContacts);

			if(toChatContacts.getRid()==0||toChatContacts.getUserid()==0) {
				throw new RuntimeException();
			}
		if(isFUpChatSession){
			chatMessageService.saveMessage(chatMessage, dbOfflineMessage, dbChatSession);
		}else {
			chatMessageService.saveMessage(dbOfflineMessage);
		}
		TUser user = userService.findByUserid(rid);
//		Byte bPlatform =  Byte.valueOf(user.getPlatform());
		if(ispush)
		{
			Map<String, LocalWebSocketSession> session = WSSManager.getSession(rid);
			if(session != null) {
				WSSManager.sendMessageText(rid, pushContent);
			}else {
				if(chatMessage.getType()==MessageType.CONTENT.getCode()||chatMessage.getType()==MessageType.SEND_IMAGE.getCode()||
						chatMessage.getType()==MessageType.SEND_VIDEO.getCode()||chatMessage.getType()==MessageType.SEND_VOICE.getCode()||
						chatMessage.getType()==MessageType.YES_GOODFIREND.getCode()) {
					ThreadPush threadPush = new ThreadPush();
					threadPush.setChatMessage(chatMessage);
					threadPush.setPushContent(pushContent);
					threadPush.settUser(user);
					threadPush.setFuser(tuser);
					threadPush.start();
					//	voip(chatMessage,pushContent,user);
					WSSManager.sendMessageText(rid, pushContent);
				}else {
					WSSManager.sendMessageText(rid, pushContent);
				}
			}
		}else {
			WSSManager.sendMessageText(rid, pushContent);
		}
	}

	/**
	 * 保存聊天下线并推送
	 * @param chatMessage
	 * @param messageTypeEnum
	 * @param toUserids
	 * @throws IOException
	 */
	private void saveChatMessage(ChatMessage chatMessage, MessageType messageTypeEnum, List<Long> toUserids,boolean isFUpChatSession,TUser user1)
			throws IOException {
		ChatMessageVo chatMessageVo = new ChatMessageVo();
		BeanUtils.copyProperties(chatMessage, chatMessageVo);
		if(chatMessageVo.getCtype()==ChatType.GROUP.getCode()||chatMessageVo.getCtype()==ChatType.CALLCENTER.getCode()) {
			chatMessageVo.setNickName(user1.getNickName());
		}
		String pushContent = new PushMessage<>(chatMessageVo, PushMessageType.CHAT).buildJson();

		List<ChatSession> dbChatSession = new ArrayList<>();
		List<OfflineMessage> dbOfflineMessage = new ArrayList<>();

		ChatSession chatSession = new ChatSession();
		chatSession.setUptime(chatMessage.getCt());
		chatSession.setCtype(chatMessage.getCtype());
		chatSession.setContent(JsonUtil.ObjectToJson(chatMessageVo));
		chatSession.setUserid(chatMessage.getFromId());
	//	if(chatMessage.getToId()!=userid) {
			chatSession.setRid(chatMessage.getToId());
	//	}
		if(chatSession.getCtype()==ChatType.CALLCENTER.getCode()) {
			chatSession.setRid(Long.valueOf(chatMessage.getGid()));
		}
		chatSession.setNoreadnum(0);
		if(isFUpChatSession){//是否更新发送人的最近会话
			dbChatSession.add(chatSession);
		}
	//	long date = new Date().getTime();
		chatMessageVo.setOff(1);
		
		String pushContentoff = new PushMessage<>(chatMessageVo, PushMessageType.CHAT).buildJson();
		toUserids.forEach(userid -> {
			// 存储离线消息
			OfflineMessage offlineMessage = new OfflineMessage();
			offlineMessage.setCt(chatMessage.getCt());
			offlineMessage.setContent(pushContentoff);// pushMsg
			offlineMessage.setMsgid(chatMessage.getId());
			offlineMessage.setUserid(userid);// 单聊临时处理
			dbOfflineMessage.add(offlineMessage);

			ChatSession toChatContacts = chatSession.copy();
			toChatContacts.setUserid(userid);
			toChatContacts.setRid(chatMessage.getFromId());
			toChatContacts.setNoreadnum(1);
			
			
			
			Optional<ChatCurrwin> chatCurrwin = chatCurrwinService.findById(userid);
			if(chatCurrwin.isPresent()){
				ChatCurrwin currWin = chatCurrwin.get();
				if(currWin.getCtype().equals(ChatType.SINGLE.getCode())){//单聊取fromid 
					if(currWin.getRid().equals(chatMessage.getFromId())){
						toChatContacts.setNoreadnum(0);
					}
				}else{
					if(currWin.getRid().equals(chatMessage.getToId())){
						toChatContacts.setNoreadnum(0);
					}
				}
			}
			
			if(chatSession.getCtype()==ChatType.SINGLE.getCode()) {
				if(!toChatContacts.getRid().equals(toChatContacts.getUserid())) {
					dbChatSession.add(toChatContacts);
				}
			}
			
			if(chatSession.getCtype()==ChatType.GROUP.getCode()||chatSession.getCtype()==ChatType.CALLCENTER.getCode()) {
				List<Groupmembers> findByGroupid = groupMemService.findByGroupid(chatMessage.getToId().intValue());
				for (Groupmembers groupmembers : findByGroupid) {
					ChatSession tosession = chatSession.copy();
					tosession.setUserid(groupmembers.getUserid());
					tosession.setRid(chatMessage.getToId());
					tosession.setNoreadnum(1);
					dbChatSession.add(tosession);
				}
				
			}
			if(toChatContacts.getRid()==0||toChatContacts.getUserid()==0) {
				throw new RuntimeException();
			}
		});

		if(isFUpChatSession) {
			chatMessageService.saveMessage(chatMessage, dbOfflineMessage, dbChatSession);
		}else {
			chatMessageService.saveMessage(chatMessage, dbOfflineMessage);
		}
	//	long time = new Date().getTime();
	//	System.out.println("发送群聊消息耗时："+(time-date));
		for (Long userid1 : toUserids) {
			TUser user = userService.findByUserid(userid1);
	//		Byte bPlatform =  Byte.valueOf(user.getPlatform());
	//		if(bPlatform == Constants.IOS_PLATFORM||bPlatform == Constants.HUAWEI_PLATFORM){
				Map<String, LocalWebSocketSession> session = WSSManager.getSession(userid1);
				if(session != null) {
					WSSManager.sendMessageText(userid1, pushContent);
				}else {
					if(chatMessage.getType()==MessageType.GROUP_CREATE.getCode()||
							chatMessage.getType()==MessageType.GROUP_JOIN.getCode()||
							chatMessage.getType()==MessageType.GROUP_OUT.getCode()||
							chatMessage.getType()==MessageType.GROUP_OVER.getCode()||
							chatMessage.getType()==MessageType.GROUP_UPDATENAME.getCode()) {
						WSSManager.sendMessageText(userid1, pushContent);
					}else {
						if(chatMessage.getType()==MessageType.CONTENT.getCode()||chatMessage.getType()==MessageType.SEND_IMAGE.getCode()||
								chatMessage.getType()==MessageType.SEND_VIDEO.getCode()||chatMessage.getType()==MessageType.SEND_VOICE.getCode()||
								chatMessage.getType()==MessageType.YES_GOODFIREND.getCode()||chatMessage.getType()==MessageType.SEND_FILE.getCode()) {
							ThreadPush threadPush = new ThreadPush();
							threadPush.setChatMessage(chatMessage);
							threadPush.setPushContent(pushContent);
							threadPush.settUser(user);
							threadPush.setFuser(user1);
							threadPush.start();
							//	voip(chatMessage,pushContent,user);
							WSSManager.sendMessageText(userid1, pushContent);
						}else {
							WSSManager.sendMessageText(userid1, pushContent);
						}
					/*	ThreadPush threadPush = new ThreadPush();
						threadPush.setChatMessage(chatMessage);
						threadPush.setPushContent(pushContent);
						threadPush.settUser(user);
						threadPush.start();
						//	voip(chatMessage,pushContent,user);
						WSSManager.sendMessageText(userid1, pushContent);*/
					}
				}
//			}else {
//				WSSManager.sendMessageText(userid1, pushContent);
//			}
		}
	}
	/**
	 * 推送消息并加验证,<br>
	 * 单聊验证是否为好友<br>
	 * 群聊验证是否为群成员,<br>
	 * callcenter验证该call是否存在
	 * @param chatMessage
	 * @param messageTypeEnum
	 * @param chatTypeEnum
	 * @return
	 * @throws Exception
	 */
	private ResultCode sendMessage(ChatMessage chatMessage, MessageType messageTypeEnum, ChatType chatTypeEnum,TUser user)
			throws Exception {

		chatMessage.setType(messageTypeEnum.getCode());

		List<Long> toUserids = new ArrayList<>();// 需要推送的用户
		if (chatTypeEnum == ChatType.SINGLE) {// 单聊 
			Goodfirend goodfirend = goodfirendService.findByUseridAndJidAndRelation(chatMessage.getFromId(), chatMessage.getToId(), 3);
			if(goodfirend ==null){
				return ResultCode.SENDMSG_NOTUSER;
			}
			chatMessage.setGid(getGid(chatMessage.getFromId(), chatMessage.getToId()));
			toUserids.add(chatMessage.getToId());
		} else if (chatTypeEnum == ChatType.GROUP) {// 群聊
			int groupid = chatMessage.getToId().intValue();
			Optional<Group> group = groupservice.findById(groupid);
			if (!group.isPresent())
				return ResultCode.SENDMSG_NOTUSER;
			chatMessage.setGid(chatMessage.getToId().toString());

			List<Groupmembers> groupmembers = group.get().getGroupmembers();
			groupmembers.forEach(item -> toUserids.add(item.getUserid()));
			if(!toUserids.remove(chatMessage.getFromId())){//如果发送人不在群中
				return ResultCode.SENDMSG_MEMNOTUSER;
			}
		}else if(chatTypeEnum == ChatType.CALLCENTER) {
			int role = 50;//50为访客角色
	//		Long callcenterId = Long.valueOf(chatMessage.getGid());
			List<Groupmembers> findByCallcenterID = groupMemService.findByGroupid(Integer.valueOf(chatMessage.getGid()));
			for (Groupmembers callCenterMem : findByCallcenterID) {
				toUserids.add(callCenterMem.getUserid());
				if(Long.valueOf(callCenterMem.getUserid()).equals(chatMessage.getFromId())) {
					role = 30;//30为管理员角色
					if(!toUserids.remove(chatMessage.getFromId())) {
						return ResultCode.SENDMSG_NOTUSER;
					}
				}
			}
			if(chatMessage.getVisitorId()!=null && chatMessage.getVisitorId()!=0 && role == 30) {
				toUserids.add(chatMessage.getVisitorId());
			}
			
		}

		saveChatMessage(chatMessage, messageTypeEnum, toUserids,true,user);
		return ResultCode.SUCCESS;
	}


	/*
	 * 单聊成功gid
	 */
	private String getGid(long from, long to) {
		return from > to ? from + "_" + to : to + "_" + from;
	}

	@GetMapping(value = "/testchat")
	public String testchat(@ApiIgnore HttpSession session) {
		return "chattest";
	}

	@GetMapping(value = "/tochat")
	public String tochat(@ApiIgnore HttpSession session) {
		return "chat";
	}

	@GetMapping(value = "/tests3")
	public String tests3(@ApiIgnore HttpSession session) {
		return "s3";
	}
	@GetMapping(value = "/group")
	public String group(@ApiIgnore HttpSession session) {
		return "group";
	}

	@ApiOperation(value = "用户退出群聊", notes = "用户退出群聊")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID", dataType="int",example="1", paramType = "query"), })
	@PostMapping(value = "/outGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> outGroup(HttpServletRequest request, @RequestParam(required = true) Integer groupid)
			throws Exception {
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		Long userId = SiteUtil.getCurrUserId(request);
		TUser currUser = SiteUtil.getCurrUser(request);

		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		Group group = groupOptional.get();
		
		Long owner = group.getOwner();
		List<Groupmembers> groupMemlist = group.getGroupmembers();
		
		Groupmembers removeGroupm = null;
		
		List<Long> uesrIds = new ArrayList<Long>();
		for (Groupmembers groupm : groupMemlist) {
			if(groupm.getUserid().equals(userId)) {
				removeGroupm = groupm;
			}
			uesrIds.add(groupm.getUserid());
		}
		uesrIds.remove(userId);
		
		if (owner.equals(userId)) {
			logger.info(userId + "解散" + groupid + "群聊");
			boolean deleteByGroupid = groupMemService.deletegro(groupid,userId);
			if (!deleteByGroupid) {
				return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
			ChatMessage message = new ChatMessage();
			message.setFromId(userId);
			message.setContent("");
			message.setClientid(UUIDGenerator.nextId());
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.GROUP.getCode());
			message.setGid(String.valueOf(groupid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(Long.valueOf(groupid));
			
			sendGroupMessage(message, MessageType.GROUP_OVER, uesrIds,false,currUser);
			return resultJsonBuild.build(ResultCode.SUCCESS);
		} 
		
		groupMemlist.remove(removeGroupm);
		if(groupMemlist.size()>=5) {
			groupMemService.deleteByUseridByGroupid(userId, groupid);
		}
		//更新群头像
		if(groupMemlist.size()<5) {
			setGroupImgAndName(currUser, group, uesrIds);
			groupMemService.deleteByUseridByGroupid(userId,group);
		}
		
		
		GroupVo groupVoOut = new GroupVo();
		BeanUtils.copyProperties(group, groupVoOut);
		
		GroupMemVo groupMemVo = new GroupMemVo();
		BeanUtils.copyProperties(removeGroupm, groupMemVo);
		groupVoOut.getGroupMem().add(groupMemVo);
		
		
		ChatMessage message = new ChatMessage();
		message.setFromId(userId);
		message.setContent(JsonUtil.ObjectToJson(groupVoOut));
		message.setClientid(UUIDGenerator.nextId());
		message.setCt(System.currentTimeMillis());
		message.setCtype(ChatType.GROUP.getCode());
		message.setGid(String.valueOf(groupid));
		message.setId(UUIDGenerator.nextId());
		message.setToId(Long.valueOf(groupid));
		sendGroupMessage(message, MessageType.GROUP_OUT, uesrIds,false,currUser);
		return resultJsonBuild.build(ResultCode.SUCCESS);
	}

	@ApiOperation(value = "用户创建群聊", notes = "用户新建群聊")
	@ApiImplicitParams({ @ApiImplicitParam(name = "ids", required = true,allowMultiple=true,dataType = "int",example="0", value = "邀请成员", paramType = "query") })
	@PostMapping(value = "/createGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<GroupVo> createGroup(HttpServletRequest request, @RequestParam(required=true)List<Long> ids)
			throws Exception {
		long starttime = System.currentTimeMillis();
		ResultJsonBuild<GroupVo> resultJsonBuild = new ResultJsonBuild<GroupVo>();
		TUser currUser =SiteUtil.getCurrUser(request);
		String uuid = UUIDGenerator.nextId();
		//查询是否为好友验证
		// 一次查询多条记录
		List<TUser> imgAndId = userService.selectByids(StringUtils.join(ids, ","),currUser.getUserid());
		
		imgAndId.add(0,currUser);
		// 凭借群昵称，头像等
		StringBuffer groupName = new StringBuffer();
		
		List<Long> uesrIds = new ArrayList<>();
		List<String> urlPath = new ArrayList<>();
		for (int i=0;i<imgAndId.size();i++) {
			TUser tUser = imgAndId.get(i);
			if(i<5) {
				groupName.append(tUser.getNickName()+",");
			}
			if(urlPath.size()<5){
				if(tUser.getImage()!=null&&tUser.getImage()!="") {
					urlPath.add(tUser.getImage());
				}
			}
			if(i != 0){
				uesrIds.add(tUser.getUserid());
			}
		}
		
		long startTime = System.currentTimeMillis();
		String imageToS3 = toImg(uuid,currUser.getUserid(),urlPath);
		long time1 = System.currentTimeMillis();
		logger.info("头像生成时间："+(time1-startTime));
		long groupct = System.currentTimeMillis();
		Group group = new Group();
		group.setCt(groupct);
		group.setUid(uuid);
		group.setImage(imageToS3);
		group.setName(groupName.toString().substring(0, groupName.length()-1));
		group.setOwner(currUser.getUserid());
		group.setGtype(1);
		group.setFlag(0);

		boolean b = groupservice.createGroup(group, imgAndId);
		if (b) {
			GroupVo groupVo = new GroupVo();
			BeanUtils.copyProperties(group, groupVo);
			List<GroupMemVo> groupMem = imgAndId.stream().map(user->{
				GroupMemVo groupMemVo = new GroupMemVo();
				groupMemVo.setCt(group.getCt());
				groupMemVo.setUserid(user.getUserid());
				groupMemVo.setUserName(user.getNickName());
				groupMemVo.setUserImage(user.getImage());
				return groupMemVo;
			}).collect(Collectors.toList());
			groupVo.setGroupMem(groupMem);
			
			ChatMessage chatMessage = new ChatMessage();
			chatMessage.setFromId(currUser.getUserid());
			chatMessage.setToId(Long.valueOf(group.getId()));
			chatMessage.setContent(JsonUtil.ObjectToJson(groupVo));
			chatMessage.setCt(System.currentTimeMillis());
			chatMessage.setCtype(ChatType.GROUP.getCode());
			chatMessage.setId(UUIDGenerator.nextId());
			chatMessage.setClientid(UUIDGenerator.nextId());
			//应客户端需求创建者也推送
			uesrIds.add(currUser.getUserid());
			sendGroupMessage(chatMessage, MessageType.GROUP_CREATE, uesrIds,true,currUser);
			
			long time2 = System.currentTimeMillis();
			logger.info("createGroup执行时间："+(time2-starttime));
			return resultJsonBuild.success(groupVo);
		} else {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
	}

	@ApiOperation(value = "用户获取群成员列表", notes = "用户获取群成员列表")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID", dataType="int",example="1", paramType = "query") })
	@PostMapping(value = "/getGroupMembers")
	@ResponseBody
	public ResultJson<List<GroupMemVo>> getGroupMembers(HttpServletRequest request,
			@RequestParam(required = true) Integer groupid) {
		Long userId = SiteUtil.getCurrUserId(request);
		ResultJsonBuild<List<GroupMemVo>> resultJsonBuild = new ResultJsonBuild<>();

		boolean flag = false;
		List<Groupmembers> list = groupMemService.findByGroupid(groupid);
		List<GroupMemVo> result = new ArrayList<GroupMemVo>();
		if (list != null) {
			for (Groupmembers item : list) {
				if(item.getUserid().equals(userId)) {
					flag = true;
				}
				TUser user = userService.findByUserid(item.getUserid());
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				GroupMemResult.setUserImage(user.getImage());
				result.add(GroupMemResult);
			}
			if(!flag){
				return resultJsonBuild.build(ResultCode.GROUP_GETMEN_ERROR);
			}
		}else {
			return resultJsonBuild.build(ResultCode.SENDMSG_NOTUSER);
		}

		return resultJsonBuild.success(result);
	}
	
	
	@ApiOperation(value = "邀请加入群", notes = "邀请加入群")
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "groupid", required = true,dataType="int",example="1", value = "群ID", paramType = "query"),
		@ApiImplicitParam(name = "ids", required = true, value = "邀请成员ids", paramType = "query")})
	@PostMapping(value = "/inGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> inGroup(HttpServletRequest request,
			@RequestParam(required=true)Integer groupid,
			@RequestParam(required=true)List<Long> ids) throws Exception{
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		
		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		Group group = groupOptional.get();
		List<Groupmembers> groupmembersList = group.getGroupmembers();
		if(groupmembersList == null || groupmembersList.size() == 0){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		List<Long> uesrIds = new ArrayList<>();
		boolean flag = false;
		for (Groupmembers groupmembers : groupmembersList) {
			boolean b = ids.contains(groupmembers.getUserid());
			if(b) {
				logger.info("ingroup error:"+groupmembers.getUserid());
				return resultJsonBuild.build(ResultCode.SUCCESS);
			}
			if(groupmembers.getUserid().equals(userId)) {
				flag = true;
			}
			uesrIds.add(groupmembers.getUserid());//旧用户成员
		}
		if(!flag) {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		uesrIds.addAll(ids);
		//查询群中所有用户信息
		List<TUser> rosterUserList = userService.selectByids(StringUtils.join(uesrIds, ","));
		if(rosterUserList == null){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		uesrIds.clear();//清空集合,推送给真实数据库用户
		
		boolean isUpGImage = groupmembersList.size()<5;
		List<String> urlPath = new ArrayList<>();
		List<Groupmembers> saveGroupmember = new ArrayList<>();
		for(TUser rosterUser:rosterUserList){
			Long rosterUserId = rosterUser.getUserid();
			if(ids.contains(rosterUserId)){//如果是新成员
				Groupmembers groupMem = new Groupmembers();
				groupMem.setCt(System.currentTimeMillis());
				groupMem.setGroupid(groupid);
				groupMem.setUserid(rosterUserId);//返回新成员
				groupMem.setUserName(rosterUser.getNickName());
				groupMem.setGtype(1);
				saveGroupmember.add(groupMem);
			}
			if(urlPath.size() < 5){
				urlPath.add(rosterUser.getImage());
			}
			uesrIds.add(rosterUser.getUserid());//需要推送的新用户成员
		}
		if(saveGroupmember.size()<=0){
			//没有新的成员
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		boolean inGroupZt = false;
		if(isUpGImage) {
			//group.setGroupName(groupName);//无需更新群名称,创建群可生成默认,参考微信
			String img = toImg(group.getUid(), userId, urlPath);
			group.setImage(img);
			inGroupZt = groupservice.inGroup(group, saveGroupmember);
		}else{
			inGroupZt = groupMemService.saveAll(saveGroupmember).size() == saveGroupmember.size();
		}
		
		if(inGroupZt){
	/*		groupmembersList.addAll(saveGroupmember);
			//新成员+旧成员,推送给客户端,旧的成员可能不需要 旧的成员,暂时推送所用成员
			List<GroupMemVo> memVoList = groupmembersList.stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				if(ids.contains(GroupMemResult.getUserid())) {
					GroupMemResult.setChange(1);
				}else{
					GroupMemResult.setChange(0);
				};
				return GroupMemResult;
			}).collect(Collectors.toList());*/
			
			// 推送消息
			
			List<GroupMemerVo> memVoList = saveGroupmember.stream().map(item -> {
				GroupMemerVo GroupMemResult = new GroupMemerVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				TUser tUser = userService.findByUserid(item.getUserid());
				GroupMemResult.setUserImage(tUser.getImage());
				GroupMemResult.setUserName(tUser.getNickName());
				GroupMemResult.setGroupImage(group.getImage());
				GroupMemResult.setGroupName(group.getName());
				return GroupMemResult;
			}).collect(Collectors.toList());
			
			
			ChatMessage message = new ChatMessage();
			message.setFromId(userId);
			message.setContent(JsonUtil.ObjectToJson(memVoList));
			message.setClientid(UUIDGenerator.nextId());
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.GROUP.getCode());
			message.setGid(String.valueOf(groupid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(Long.valueOf(groupid));
			
			sendGroupMessage(message, MessageType.GROUP_JOIN, uesrIds, true,currUser);
			return resultJsonBuild.build(ResultCode.SUCCESS);
		}
		return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
	}
	@ApiOperation(value = "扫码加入群", notes = "扫码加入群")
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "groupid", required = true,dataType="int",example="1", value = "群ID", paramType = "query"),
		@ApiImplicitParam(name = "gtype", required = true, dataType="int",example="1",value = "加入群聊类型", paramType = "query")})
	@PostMapping(value = "/inTwoCodeGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> inTwoCodeGroup(HttpServletRequest request,
			@RequestParam(required=true)Integer groupid,
			@RequestParam(required=true)int gtype) throws Exception{
		TUser user = SiteUtil.getCurrUser(request);
		Long userId = user.getUserid();
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		
		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		Group group = groupOptional.get();
		List<Groupmembers> groupmembersList = group.getGroupmembers();
		if(groupmembersList == null || groupmembersList.size() == 0){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		List<Long> uesrIds = new ArrayList<>();
		for (Groupmembers groupmembers : groupmembersList) {
			boolean b = userId.equals(groupmembers.getUserid());
			if(b) {
				return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
			uesrIds.add(groupmembers.getUserid());//旧用户成员
		}
		uesrIds.add(userId);
		//查询群中所有用户信息
		List<TUser> rosterUserList = userService.selectByids(StringUtils.join(uesrIds, ","));
		if(rosterUserList == null){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		uesrIds.clear();//清空集合,推送给真实数据库用户
		
		boolean isUpGImage = groupmembersList.size()<5;
		List<String> urlPath = new ArrayList<>();
		List<Groupmembers> saveGroupmember = new ArrayList<>();
		for(TUser rosterUser:rosterUserList){
			Long rosterUserId = rosterUser.getUserid();
			if(userId.equals(rosterUserId)){//如果是新成员
				Groupmembers groupMem = new Groupmembers();
				groupMem.setCt(System.currentTimeMillis());
				groupMem.setGroupid(groupid);
				groupMem.setUserid(rosterUserId);//返回新成员
				groupMem.setUserName(rosterUser.getNickName());
				groupMem.setGtype(1);
				saveGroupmember.add(groupMem);
			}
			if(urlPath.size() < 5){
				urlPath.add(rosterUser.getImage());
			}
			uesrIds.add(rosterUser.getUserid());//需要推送的新用户成员
		}
		if(saveGroupmember.size()<=0){
			//没有新的成员
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		boolean inGroupZt = false;
		if(isUpGImage) {
			//group.setGroupName(groupName);//无需更新群名称,创建群可生成默认,参考微信
			String img = toImg(group.getUid(), userId, urlPath);
			group.setImage(img);
			inGroupZt = groupservice.inGroup(group, saveGroupmember);
		}else{
			inGroupZt = groupMemService.saveAll(saveGroupmember).size() == saveGroupmember.size();
		}
		
		if(inGroupZt){
			/*		groupmembersList.addAll(saveGroupmember);
			//新成员+旧成员,推送给客户端,旧的成员可能不需要 旧的成员,暂时推送所用成员
			List<GroupMemVo> memVoList = groupmembersList.stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				if(ids.contains(GroupMemResult.getUserid())) {
					GroupMemResult.setChange(1);
				}else{
					GroupMemResult.setChange(0);
				};
				return GroupMemResult;
			}).collect(Collectors.toList());*/
			
			// 推送消息
			
			List<GroupMemVo> memVoList = saveGroupmember.stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				TUser tUser = userService.findByUserid(item.getUserid());
				GroupMemResult.setUserImage(tUser.getImage());
				GroupMemResult.setUserName(tUser.getNickName());
				return GroupMemResult;
			}).collect(Collectors.toList());
			
			
			ChatMessage message = new ChatMessage();
			message.setFromId(userId);
			message.setContent(JsonUtil.ObjectToJson(memVoList));
			message.setClientid(UUIDGenerator.nextId());
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.GROUP.getCode());
			message.setGid(String.valueOf(groupid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(Long.valueOf(groupid));
//			uesrIds.remove(userId);
			sendGroupMessage(message, MessageType.GROUP_JOIN, uesrIds, true,user);
			
			List<GroupMemVo> memVoList1 = group.getGroupmembers().stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				TUser tUser = userService.findByUserid(item.getUserid());
				GroupMemResult.setUserImage(tUser.getImage());
				GroupMemResult.setUserName(tUser.getNickName());
				return GroupMemResult;
			}).collect(Collectors.toList());
			memVoList1.addAll(memVoList);
			
			GroupVo groupVo = new GroupVo();
			org.springframework.beans.BeanUtils.copyProperties(group, groupVo);
			groupVo.setGroupMem(memVoList1);
			return resultJsonBuild.success(groupVo);
		}
		return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
	}
	
	@ApiOperation(value = "移除群聊", notes = "移除群聊")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID",dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "ids", required = true, value = "移除成员ids", paramType = "query")})
	@PostMapping(value = "/removerGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> removerGroup(HttpServletRequest request,@RequestParam(required = true)int groupid,@RequestParam(required = true)List<Long> ids) throws Exception{
		Long userId = SiteUtil.getCurrUserId(request);
		TUser currUser = SiteUtil.getCurrUser(request);
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		//验证是否为群主 并拿到grid
		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		
		Group group = groupOptional.get();
		List<Groupmembers> groupmembers = group.getGroupmembers();
		if(!group.getOwner().equals(userId)) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		if(groupmembers==null) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		
		List<Groupmembers> removeGroupm = new ArrayList<Groupmembers>();
		List<Long> idsAll = new ArrayList<Long>();
		
		List<Long> userIdlist = new ArrayList<>();
		for (int i = 0; i < groupmembers.size(); i++) {
			Long groupmemberUserid = groupmembers.get(i).getUserid();
			if(!ids.contains(groupmemberUserid)) {
				userIdlist.add(groupmemberUserid);
			}else {
				removeGroupm.add(groupmembers.get(i));
			}
			idsAll.add(groupmemberUserid);
		}
		
		setGroupImgAndName(currUser, group, userIdlist);
		
		groupMemService.saveImgAndDel(removeGroupm,group);
		
		////
/*		List<GroupMemVo> memVoList = removeGroupm.stream().map(item -> {
			GroupMemVo GroupMemResult = new GroupMemVo();
			org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				GroupMemResult.setChange(1);
			return GroupMemResult;
		}).collect(Collectors.toList());*/
		////
		ChatMessage message = new ChatMessage();
		message.setFromId(userId);
		message.setContent(JsonUtil.ObjectToJson(removeGroupm));
		message.setClientid(UUIDGenerator.nextId());
		message.setCt(System.currentTimeMillis());
		message.setCtype(ChatType.GROUP.getCode());
		message.setGid(String.valueOf(groupid));
		message.setId(UUIDGenerator.nextId());
		message.setToId(Long.valueOf(groupid));
		sendGroupMessage(message, MessageType.GROUP_REMOVE, idsAll, true,currUser);
		
		return resultJsonBuild.build(ResultCode.SUCCESS);
		
	}

	private void setGroupImgAndName(TUser currUser, Group group, List<Long> userIdlist) throws Exception {
		List<TUser> imgAndId = userService.selectByids(StringUtils.join(userIdlist,","));
		List<String> urlPath = new ArrayList<>();
		List<String> groupName = new ArrayList<>();
		String image = "";
		String img = "";
		for (TUser tUser : imgAndId) {
			groupName.add(tUser.getNickName());
			if(tUser.getUserid().equals(group.getOwner())) {
				image = tUser.getImage();
				urlPath.add(image);
				continue;
			}
			if(urlPath.size()<5){
				urlPath.add(tUser.getImage());
			}
		}
	//	urlPath.add(0,currUser.getImage());
		if(urlPath.size()<2) {
			group.setImage(image);
		}else {
			img = toImg(group.getUid(), currUser.getUserid(), urlPath);
			group.setImage(img);
		}
		if(group.getFlag()==0) {
			group.setName(StringUtils.join(groupName,","));
		}
	}
	/*
	public static void main(String[] args) {
		System.out.println(UUIDGenerator.nextId());
		ChatMessageController chatMessageController = new ChatMessageController();
		List<String> urlPath = new ArrayList<>();
		urlPath.add("http://ftpcn.jingcailvtu.org:8001/UserHeadPic/26/1458876648236/faceImage.png");
		urlPath.add("http://ftpcn.jingcailvtu.org:8001/UserHeadPic/25/1451900148560/faceImage.png");
		urlPath.add("http://resource.jingcailvtu.org/3379796/UserHeaderModule/1496210288703.jpeg");
		urlPath.add("http://newresource.jingcailvtu.org/imagess/54/UserHeaderModule/3AF391C6-9727-4966-A8FF-8667A17C578F.jpeg");
		urlPath.add("http://resource.jingcailvtu.org/1966/s3_file_user_header/1523250133539cropheader.png");
		
		try {
			String img = chatMessageController.toImg("d41b0898cdc8447d8851fa1c5325aa6b", 1L, urlPath);
			System.out.println(img);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}*/
	//生成群聊头像
//	private static  ExecutorService executorService = Executors.newFixedThreadPool(10);

	public String toImg(String grid,Long userId,List<String> urlPath) throws Exception {
		long stime = new Date().getTime();
//		DownloadImages downloadImages = new DownloadImages();
//		downloadImages.setUrlPath(urlPath);
		List<BufferedImage> list = DownloadImages.zdownloads(urlPath);
	//	Future<List<BufferedImage>> downloadimg = executorService.submit(downloadImages);
//		List<BufferedImage> images = DownloadImages.downloads(urlPath);
//		List<BufferedImage> list = downloadimg.get();
		long time2 = new Date().getTime();
		logger.info("下载图片耗时"+(time2-stime));
		long stime1 = new Date().getTime();
		BufferedImage generate = ImgUtils.generate(list);
		long time21 = new Date().getTime();
		logger.info("合成头像耗时"+(time21-stime1));
		String clientid = UUIDGenerator.nextId();
		
		String uploadKey = clientid+".jpg";
		long stime11 = new Date().getTime();
		Tos3 tos3 = new Tos3();
		tos3.setGroupId(grid+"/"+userId+"/");
		tos3.setKey(uploadKey);
		tos3.setImage(generate);
		tos3.start();
		long time2111 = new Date().getTime();
		logger.info("上传时头像到s3耗时"+(time2111-stime11));
		String toS3 = S3_HOST+DEFAULT_BUCKET+"/"+DEFAULT_GROUP_FOLDER+"/"+grid+"/"+userId+"/"+uploadKey;
		logger.info("return S3 url{"+grid+"}"+toS3);
		return toS3;
	//	return imageToS3;
	}
	
	@ApiOperation(value = "更改群名称", notes = "更改群名称")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID",dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "gname", required = true, value = "更改的群名称", paramType = "query")})
	@PostMapping(value = "/updateGroupName")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> updateGroupName(HttpServletRequest request,@RequestParam(required = true)Integer groupid,@RequestParam(required = true)String gname) throws IOException{
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
		ResultJsonBuild<Object> resultJson = new ResultJsonBuild<Object>();
		Optional<Group> group = groupservice.findById(groupid);
		
		if(group.isPresent()) {
			Group group2 = group.get();
			List<Groupmembers> groupmembers = group.get().getGroupmembers();
			boolean b = false;
			for (Groupmembers groupmembers2 : groupmembers) {
				if(groupmembers2.getUserid().equals(userId)){
					group2.setName(gname);
					group2.setFlag(1);
					b = groupservice.save(group2)!=null;
				}
			}
			if(b) {
				GroupVo groupVo = new GroupVo();
				BeanUtils.copyProperties(group2, groupVo);
				
				ChatMessage message = new ChatMessage();
				message.setFromId(userId);
				message.setContent(JsonUtil.ObjectToJson(groupVo));
				message.setClientid(UUIDGenerator.nextId());
				message.setCt(System.currentTimeMillis());
				message.setCtype(ChatType.GROUP.getCode());
				message.setGid(String.valueOf(groupid));
				message.setId(UUIDGenerator.nextId());
				message.setToId(Long.valueOf(groupid));
				
				
				List<Long> idsAll = new ArrayList<Long>();
				for (Groupmembers member : groupmembers) {
					idsAll.add(member.getUserid());
				}
		//		idsAll.remove(userId);
				sendGroupMessage(message, MessageType.GROUP_UPDATENAME, idsAll, true,currUser);
				return resultJson.build(ResultCode.SUCCESS);
			}else {
				return resultJson.build(ResultCode.GROUP_UPNAME_ERROR);
			}
		}else {
			return resultJson.build(ResultCode.UNKONW_ERROR);
		}
	}
	
	@ApiOperation(value = "获取通知", notes = "获取通知")
	@PostMapping(value = "/getNotice")
	@ResponseBody
	public ResultJson<List<ChatNotifiedVo>> getNotice(HttpServletRequest request) throws IOException {
		ResultJson<List<ChatNotifiedVo>> resultJson = new ResultJson<List<ChatNotifiedVo>>();
		
		Long userid = SiteUtil.getCurrUserId(request);
		
		List<ChatNotified> notice = chatNotifiedService.findByUserid(userid);
		
		
		List<ChatNotifiedVo> memVoList = notice.stream().map(item -> {
			ChatNotifiedVo chatNotifiedVo = new ChatNotifiedVo();
			org.springframework.beans.BeanUtils.copyProperties(item, chatNotifiedVo);
			return chatNotifiedVo;
		}).collect(Collectors.toList());
		
		return resultJson.setObj(memVoList);
	}
	@ApiOperation(value = "删除修改未读通知", notes = "修改未读删除通知")
	@ApiImplicitParams({@ApiImplicitParam(name = "msgId", required = true, value = "消息ID",dataType="String", paramType = "query"),
		@ApiImplicitParam(name = "flag", required = true, value = "1删2改",dataType="int",example="0", paramType = "query")})
	@PostMapping(value = "/delNotice")
	@ResponseBody
	public ResultJson<Object> delNotice(HttpServletRequest request,@RequestParam(required = true)String msgId,@RequestParam(required = true)int flag) throws IOException {
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		Long userid = SiteUtil.getCurrUserId(request);
		
		ChatNotified chatNotified = chatNotifiedService.findByUseridAndMsgId(userid,msgId);
		if(chatNotified!=null) {
			if(flag==1) {
				chatNotifiedService.deleteById(msgId);
				return resultJsonBuild.success();
			}else {
				chatNotified.setReaded(0);
				boolean b = chatNotifiedService.save(chatNotified)!=null;
				return b?resultJsonBuild.success():resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
		}else {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
	}

	/**
	 * 
	 * @param request
	 * @param session
	 * @param content
	 * @param platForm
	 * @param token
	 * @param resource
	 * @param msgType
	 * @param region
	 * @param strArgs
	 * @return
	 * @throws IOException 
	 */
	
	@ApiOperation(value = "生成二维码", notes = "生成二维码")
	@GetMapping(value = "/generatingCode")
	@ApiImplicitParams({@ApiImplicitParam(name = "msgId", required = true, value = "消息ID",dataType="String", paramType = "query")})
	@ResponseBody
	public void generatingCode(HttpServletRequest request,HttpServletResponse response,@RequestParam(required = true)String msgId) throws IOException {
	//	long mostSignificantBits = UUID.randomUUID().getMostSignificantBits();
	//	String msgId = String.valueOf(mostSignificantBits);
		try {
			QrCodeCreateUtil.createQrCode(twoCodeUrl+msgId,900,"JPEG",response.getOutputStream());
		} catch (WriterException | IOException e) {
			logger.error("生成二维码 error ："+e);
			e.printStackTrace();
		}
		response.setContentType("image/jpg");
		response.flushBuffer();
	}
	@ApiOperation(value = "传递登录信息", notes = "传递登录信息")
	@ApiImplicitParams({@ApiImplicitParam(name = "msgId", required = true, value = "ID",dataType="String", paramType = "query")})
	@RequestMapping(value = "/codeloginMessage")
	@ResponseBody
	public ResultJson<Object> codeloginMessage(HttpServletRequest request,
			@RequestParam(required = true)String msgId,@RequestParam(required = true)String xAuthToken) {
		TUser tUser = SiteUtil.getCurrUser(request);
		String nickName = tUser.getNickName();
		Long userid = tUser.getUserid();
		String image = tUser.getImage();
		
		JSONObject jsonObject = new JSONObject();
		jsonObject.accumulate("nickName", nickName);
		jsonObject.accumulate("userid", userid);
		jsonObject.accumulate("image", image);
		jsonObject.accumulate("xAuthToken", xAuthToken);
		
		String content = jsonObject.toString();
		try {
			WSSManager.sendMessageText(Long.valueOf(msgId), content);
		//	pushNotice(UUIDGenerator.nextId(), userid, content,MessageType.GENERATINGCODE.getCode());
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		} catch (IOException e) {
			logger.error("消息推送失败 error ："+e);
			e.printStackTrace();
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		
	}
	
	/*
	@ApiOperation(value = "搜索", notes = "搜索")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "nickName", required = true, value = "用户昵称",dataType="String", paramType = "query")})
	@PostMapping(value = "search")
	@ResponseBody
	public ResultJson<Map<String, List<SearchVo>>> search(HttpServletRequest request,@RequestParam(required = true)String nickName) {
		Long userId = SiteUtil.getCurrUserId(request);
		
		ResultJson<Map<String, List<SearchVo>>> resultJson = new ResultJson<Map<String, List<SearchVo>>>();
		
		Map<String, List<SearchVo>> resultmap = new HashMap<String, List<SearchVo>>();
		
		//模糊查询联系人
		List<Map<String,Object>> searchByContactslist = null;
		List<Map<String,Object>> mapids = goodfirendService.findByUseridAndRelation(userId);
		String ids = null;
		if(mapids.size()>0 && mapids!=null) {
			StringBuffer stringBuffer = new StringBuffer();
			for (Map<String,Object> id : mapids) {
				stringBuffer.append(id.get("jid")+",");
			}
			ids = stringBuffer.toString().substring(0,stringBuffer.length()-1);
			searchByContactslist = userService.searchByContacts(ids,nickName);
		}
		
		List<SearchVo> resultlist = new ArrayList<SearchVo>();
		if(searchByContactslist.size()>0 && searchByContactslist!=null) {
			for (Map<String,Object> map : searchByContactslist) {
				SearchVo searchVo = new SearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setUserid(Long.valueOf(map.get("userid").toString()));
				searchVo.setNickName(map.get("nickName").toString());
				resultlist.add(searchVo);
			}
			resultmap.put("contacts", resultlist);
		}
		
		//群组模糊查询联系人OR群名称
		List<Map<String,Object>> searchByUserName = groupMemService.searchByUserName(userId,nickName);

		List<Map<String, Object>> searchByGroupName = groupMemService.searchByGroupName(userId,nickName);
		
		List<SearchVo> resultgrouplist = new ArrayList<SearchVo>();
		if(searchByUserName.size()>0 && searchByUserName!=null) {
			for (Map<String,Object> map : searchByUserName) {
				SearchVo searchVo = new SearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setUserid(Long.valueOf(map.get("id").toString()));
				searchVo.setNickName(map.get("name").toString());
				searchVo.setUserName(map.get("userName").toString());
				resultgrouplist.add(searchVo);
			}
		}
		if(searchByGroupName.size()>0 && searchByGroupName!=null) {
			for (Map<String,Object> map : searchByGroupName) {
				SearchVo searchVo = new SearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setUserid(Long.valueOf(map.get("id").toString()));
				searchVo.setNickName(map.get("name").toString());
				resultgrouplist.add(searchVo);
			}
		}
		if(resultgrouplist.size()>0) {
			resultmap.put("group", resultgrouplist);
		}
		
		//步吧搜索陌生人
		List<Map<String,Object>> searchByboobuzlist = userService.searchByboobuz(nickName);
		
		List<SearchVo> resultgroupboobuzlist = new ArrayList<SearchVo>();
		if(searchByboobuzlist.size()>0 && searchByboobuzlist!=null) {
			for (Map<String,Object> map : searchByboobuzlist) {
				SearchVo searchVo = new SearchVo();
				if(!map.containsValue(null)) {
					searchVo.setImage(map.get("image").toString());
				}
				searchVo.setUserid(Long.valueOf(map.get("userid").toString()));
				searchVo.setNickName(map.get("nickName").toString());
				resultgroupboobuzlist.add(searchVo);
			}
			resultmap.put("boobuz", resultgroupboobuzlist);
		}
		
		return resultJson.setObj(resultmap);
	}*/
	
	
	
	@ApiOperation(value = "搜索", notes = "搜索")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "nickName", required = true, value = "用户昵称",dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "startPage", required = true, value = "起始页码",dataType="int",example="0", paramType = "query"),
			@ApiImplicitParam(name = "rows", required = true, value = "条数",dataType="int",example="10", paramType = "query")
			})
	@PostMapping(value = "search")
	@ResponseBody
	public ResultJson<List<SearchVo>> search(HttpServletRequest request,@RequestParam(required = true)String nickName,
			@RequestParam(required = true)int startPage,@RequestParam(required = true)int rows) {
		ResultJson<List<SearchVo>> resultJson = new ResultJson<List<SearchVo>>();
		
		//步吧搜索陌生人
		List<Map<String,Object>> searchByboobuzlist = userService.searchByboobuz(nickName,startPage,rows);
		
		List<SearchVo> resultgroupboobuzlist = new ArrayList<SearchVo>();
		if(searchByboobuzlist.size()>0 && searchByboobuzlist!=null) {
			for (Map<String,Object> map : searchByboobuzlist) {
				SearchVo searchVo = new SearchVo();
				if(!map.containsValue(null)) {
					searchVo.setImage(map.get("image").toString());
				}else {
					searchVo.setImage("");
				}
				searchVo.setUserid(Long.valueOf(map.get("userid").toString()));
				searchVo.setNickName(map.get("nickName").toString());
				resultgroupboobuzlist.add(searchVo);
			}
		}
		
		return resultJson.setObj(resultgroupboobuzlist);
	}
	
	@ApiOperation(value = "web搜索", notes = "web搜索")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "nickName", required = true, value = "搜索关键字",dataType="String", paramType = "query")})
	@PostMapping(value = "searchForContactsAndGroup")
	@ResponseBody
	public ResultJson<Map<String, List<WebSearchVo>>> searchForContactsAndGroup(HttpServletRequest request,@RequestParam(required = true)String nickName) {
		Long userId = SiteUtil.getCurrUserId(request);
		
		ResultJson<Map<String, List<WebSearchVo>>> resultJson = new ResultJson<Map<String, List<WebSearchVo>>>();
		
		Map<String, List<WebSearchVo>> resultmap = new HashMap<String, List<WebSearchVo>>();
		
		//
		List<Map<String,Object>> searchByContactslist = null;
		List<Map<String,Object>> mapids = goodfirendService.findByUseridAndRelation(userId);
		String ids = null;
		if(mapids.size()>0 && mapids!=null) {
			StringBuffer stringBuffer = new StringBuffer();
			for (Map<String,Object> id : mapids) {
				stringBuffer.append(id.get("jid")+",");
			}
			ids = stringBuffer.toString().substring(0,stringBuffer.length()-1);
			searchByContactslist = userService.searchByContacts(ids,nickName);
		}
		
		List<WebSearchVo> resultlist = new ArrayList<WebSearchVo>();
		if(searchByContactslist.size()>0 && searchByContactslist!=null) {
			for (Map<String,Object> map : searchByContactslist) {
				WebSearchVo searchVo = new WebSearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setUserid(Long.valueOf(map.get("userid").toString()));
				searchVo.setNickName(map.get("nickName").toString());
				resultlist.add(searchVo);
			}
			resultmap.put("contacts", resultlist);
		}
		
		//
		List<Map<String,Object>> searchByUserName = groupMemService.searchByUserName(userId,nickName);

		List<Map<String, Object>> searchByGroupName = groupMemService.searchByGroupName(userId,nickName);
		
		List<WebSearchVo> resultgrouplist = new ArrayList<WebSearchVo>();
		if(searchByUserName.size()>0 && searchByUserName!=null) {
			for (Map<String,Object> map : searchByUserName) {
				WebSearchVo searchVo = new WebSearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setUserid(Long.valueOf(map.get("id").toString()));
				searchVo.setNickName(map.get("name").toString());
				searchVo.setUserName(map.get("userName").toString());
				resultgrouplist.add(searchVo);
			}
		}
		if(searchByGroupName.size()>0 && searchByGroupName!=null) {
			for (Map<String,Object> map : searchByGroupName) {
				WebSearchVo searchVo = new WebSearchVo();
				searchVo.setImage(map.get("image").toString());
				searchVo.setGroupId(Long.valueOf(map.get("id").toString()));
				searchVo.setNickName(map.get("name").toString());
				resultgrouplist.add(searchVo);
			}
		}
		if(resultgrouplist.size()>0) {
			resultmap.put("group", resultgrouplist);
		}
		
		
		return resultJson.setObj(resultmap);
	}
	
	
	
	
	@ApiOperation(value = "生成二维码添加好友", notes = "生成二维码添加好友")
	@GetMapping(value = "/addfirendByTwoCode")
	@ApiImplicitParams({@ApiImplicitParam(name = "flag", required = true, value = "区分中英文",dataType="int",example="0", paramType = "query")})
	@ResponseBody
	public void addfirendByTwoCode(HttpServletRequest request,HttpServletResponse response,@RequestParam(required = true)int flag) throws IOException {
		Long userId = SiteUtil.getCurrUserId(request);
		String encryptBoobuz = encryptBoobuz(userId.longValue());
		try {
			if(flag==4) {
				QrCodeCreateUtil.createQrCode(sharelink+encryptBoobuz,900,"JPEG",response.getOutputStream());
			}else if(flag==8){
				QrCodeCreateUtil.createQrCode(sharelink_google+encryptBoobuz,900,"JPEG",response.getOutputStream());
			}
		} catch (WriterException | IOException e) {
			logger.error("生成二维码 error ："+e);
			e.printStackTrace();
		}
		response.setContentType("image/jpg");
		response.flushBuffer();
	}
	
	@ApiOperation(value = "添加poi绑定", notes = "添加poi绑定")
	@GetMapping(value = "/addPOI")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "userid", required = true, value = "绑定poi的用户id",dataType="int",example="0", paramType = "query"),
		@ApiImplicitParam(name = "poiId", required = true, value = "poiId",dataType="String", paramType = "query"),
		@ApiImplicitParam(name = "image", required = true, value = "poi图片",dataType="String", paramType = "query"),
		@ApiImplicitParam(name = "nickName", required = true, value = "绑定poi名称",dataType="String", paramType = "query")
	})
	@ResponseBody
	public ResultJson<Object> addPOI(HttpServletRequest request,HttpServletResponse response,
			@RequestParam(required = true)Long userid,
			@RequestParam(required = true)String poiId,
			@RequestParam(required = true)String image,
			@RequestParam(required = true)String nickName
			){
		Group findByPoiId = groupservice.findByPoiId(poiId);
		if(findByPoiId!=null) {
			return ResultJsonBuild.buildObj(ResultCode.POI_ERROR);
		}
		long millis = System.currentTimeMillis();
		String nextId = UUIDGenerator.nextId();
		Group group = new Group();
		group.setCt(millis);
		group.setGtype(4);
		group.setImage(image);
		group.setName(nickName);
		group.setOwner(userid);
		group.setUid(nextId);
		group.setPoiId(poiId);
		Groupmembers groupmembers = new Groupmembers();
		groupmembers.setCt(millis);
		groupmembers.setUserid(userid);
		groupmembers.setUserName(nickName);
		groupmembers.setGtype(CallCenterType.CUSTOM.getCode());
		boolean saveAddPOI = groupservice.saveAddPOI(group,groupmembers);
		if(saveAddPOI) {
			return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
		}else {
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		
	}
	
	@ApiOperation(value = "根据userid获取绑定人POI", notes = "根据userid获取绑定人POI")
	@GetMapping(value = "/getPOIIdByUserId")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "userId", required = true, value = "userId",dataType="int",example="0", paramType = "query"),
	})
	@ResponseBody
	public ResultJson<Object> getPOIIdByUserId(HttpServletRequest request,
			@RequestParam(required = true)Long userId){
		ResultJson<Object> resultJson = new ResultJson<Object>();
		Group group = groupservice.findByOwnerAndGtype(userId,4);
		
		JSONObject jsonObject = new JSONObject();
		if(group!=null) {
			if(StringUtil.isEmpty(group.getPoiId())) {
				jsonObject.accumulate("poiId", "");
			}else {
				jsonObject.accumulate("poiId", group.getPoiId());
			}
		}else {
			jsonObject.accumulate("poiId", "");
		}
		return resultJson.setObj(jsonObject);
	}
	@ApiOperation(value = "根据userid获取绑定人POI", notes = "根据userid获取绑定人POI")
	@GetMapping(value = "/getUserIdByPoiId")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "poiId", required = true, value = "poiId",dataType="String", paramType = "query"),
	})
	@ResponseBody
	public ResultJson<Object> getUserIdByPoiId(HttpServletRequest request,
			@RequestParam(required = true)String poiId){
		ResultJson<Object> resultJson = new ResultJson<Object>();
		Group group = groupservice.findByPoiIdAndGtype(poiId,4);
		
		JSONObject jsonObject = new JSONObject();
		if(group!=null) {
			if(group.getOwner()==null||group.getOwner()<1) {
				jsonObject.accumulate("userId", 0);
			}else {
				jsonObject.accumulate("userId", group.getOwner());
			}
		}else {
			jsonObject.accumulate("userId", 0);
		}
		return resultJson.setObj(jsonObject);
	}
	
	
	
	
	
	
	@ApiOperation(value = "根据poi获取绑定人id", notes = "根据poi获取绑定人id")
	@GetMapping(value = "/getCallCenterByPoiId")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "poiId", required = true, value = "poiId",dataType="String", paramType = "query"),
	})
	@ResponseBody
	public ResultJson<GetIdByPOIVo> getCallCenterByPoiId(HttpServletRequest request,HttpServletResponse response,
			@RequestParam(required = true)String poiId
			){
		ResultJson<GetIdByPOIVo> resultJson = new ResultJson<GetIdByPOIVo>();
		
		Long userId = SiteUtil.getCurrUserId(request);
		Group group = groupservice.findByPoiId(poiId);
		if(group==null) {
			return resultJson.setObj(null);
		}
		GetIdByPOIVo getIdByPOIVo = new GetIdByPOIVo();
		List<Groupmembers> groupmembers = group.getGroupmembers();
		boolean b = false;
		for (Groupmembers groupmembers2 : groupmembers) {
			b = groupmembers2.getUserid().equals(userId);
			if(b) {break;}
		}
		if(group.getOwner().equals(userId)) {
			getIdByPOIVo.setCallcenterRole(CallRoleType.OWNER.getCode());
		}else if(b) {
			getIdByPOIVo.setCallcenterRole(CallRoleType.MEMBER.getCode());
		}else {
			getIdByPOIVo.setCallcenterRole(CallRoleType.NONE.getCode());
		}
		getIdByPOIVo.setCallcenterID(group.getId());
		getIdByPOIVo.setCallcenterType(group.getGtype());
		getIdByPOIVo.setCallcenterName(group.getName());
		getIdByPOIVo.setCallcenterJID(group.getOwner());
		getIdByPOIVo.setCallcenterImgurl(group.getImage());
		getIdByPOIVo.setUserid(userId);
	//	getIdByPOIVo.setCcenterCountryCode("private");
		return resultJson.setObj(getIdByPOIVo);
	}
	@ApiOperation(value = "根据callid获取绑定人id", notes = "根据poi获取绑定人id")
	@GetMapping(value = "/getPOIByCallId")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "callid", required = true, value = "callid",dataType="int",example="0", paramType = "query"),
	})
	@ResponseBody
	public ResultJson<GetCallIdByPOIVo> getPOIByCallId(HttpServletRequest request,HttpServletResponse response,
			@RequestParam(required = true)int callid
			){
		ResultJson<GetCallIdByPOIVo> resultJson = new ResultJson<GetCallIdByPOIVo>();
		
		Long userId = SiteUtil.getCurrUserId(request);
		Optional<Group> findById = groupservice.findById(callid);
		Group group = null;
		if(findById.isPresent()) {
			group = findById.get();
		}
		if(group==null) {
			return resultJson.setObj(null);
		}
		GetCallIdByPOIVo getIdByPOIVo = new GetCallIdByPOIVo();
		List<Groupmembers> groupmembers = group.getGroupmembers();
		boolean b = false;
		for (Groupmembers groupmembers2 : groupmembers) {
			b = groupmembers2.getUserid().equals(userId);
			if(b) {break;}
		}
		if(group.getOwner().equals(userId)) {
			getIdByPOIVo.setCallcenterRole(CallRoleType.OWNER.getCode());
		}else if(b) {
			getIdByPOIVo.setCallcenterRole(CallRoleType.MEMBER.getCode());
		}else {
			getIdByPOIVo.setCallcenterRole(CallRoleType.NONE.getCode());
		}
		getIdByPOIVo.setCallcenterID(group.getId());
		getIdByPOIVo.setCallcenterType(group.getGtype());
		getIdByPOIVo.setCallcenterName(group.getName());
		getIdByPOIVo.setCallcenterJID(group.getOwner());
		getIdByPOIVo.setCallcenterImgurl(group.getImage());
		//	getIdByPOIVo.setCcenterCountryCode("private");
		return resultJson.setObj(getIdByPOIVo);
	}
	
	
	@ApiOperation(value = "邀请加入callcenter", notes = "邀请加入callcenter")
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "groupid", required = true,dataType="int",example="1", value = "群ID", paramType = "query"),
		@ApiImplicitParam(name = "ids", required = true, value = "邀请成员ids", paramType = "query")})
	@PostMapping(value = "/inCallCenterGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> inCallCenterGroup(HttpServletRequest request,
			@RequestParam(required=true)Integer groupid,
			@RequestParam(required=true)List<Long> ids) throws Exception{
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		
		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		CallCenterType centerType = CallCenterType.valueOf(groupOptional.get().getGtype());
		if(centerType==CallCenterType.UNKNOW) {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		Group group = groupOptional.get();
		List<Groupmembers> groupmembersList = group.getGroupmembers();
		if(groupmembersList == null || groupmembersList.size() == 0){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		
		List<Long> uesrIds = new ArrayList<>();
		boolean flag = false;
		for (Groupmembers groupmembers : groupmembersList) {
			boolean b = ids.contains(groupmembers.getUserid());
			if(b) {
				return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
			if(groupmembers.getUserid().equals(userId)) {
				flag = true;
			}
			uesrIds.add(groupmembers.getUserid());//旧用户成员
		}
		if(!flag) {
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		uesrIds.addAll(ids);
		//查询群中所有用户信息
		List<TUser> rosterUserList = userService.selectByids(StringUtils.join(uesrIds, ","));
		if(rosterUserList == null){
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		uesrIds.clear();//清空集合,推送给真实数据库用户
		
		List<String> urlPath = new ArrayList<>();
		List<Groupmembers> saveGroupmember = new ArrayList<>();
		for(TUser rosterUser:rosterUserList){
			Long rosterUserId = rosterUser.getUserid();
			if(ids.contains(rosterUserId)){//如果是新成员
				Groupmembers groupMem = new Groupmembers();
				groupMem.setCt(System.currentTimeMillis());
				groupMem.setGroupid(groupid);
				groupMem.setUserid(rosterUserId);//返回新成员
				groupMem.setUserName(rosterUser.getNickName());
				groupMem.setGtype(ChatType.GROUP.getCode());//枚举
				saveGroupmember.add(groupMem);
			}
			if(urlPath.size() < 5){
				urlPath.add(rosterUser.getImage());
			}
			uesrIds.add(rosterUser.getUserid());//需要推送的新用户成员
		}
		if(saveGroupmember.size()<=0){
			//没有新的成员
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		}
		boolean inGroupZt = false;
		inGroupZt = groupMemService.saveAll(saveGroupmember).size() == saveGroupmember.size();
		
		
		if(inGroupZt){
	/*		groupmembersList.addAll(saveGroupmember);
			//新成员+旧成员,推送给客户端,旧的成员可能不需要 旧的成员,暂时推送所用成员
			List<GroupMemVo> memVoList = groupmembersList.stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				if(ids.contains(GroupMemResult.getUserid())) {
					GroupMemResult.setChange(1);
				}else{
					GroupMemResult.setChange(0);
				};
				return GroupMemResult;
			}).collect(Collectors.toList());*/
			
			// 推送消息
			
			List<GroupMemVo> memVoList = saveGroupmember.stream().map(item -> {
				GroupMemVo GroupMemResult = new GroupMemVo();
				org.springframework.beans.BeanUtils.copyProperties(item, GroupMemResult);
				TUser tUser = userService.findByUserid(item.getUserid());
				GroupMemResult.setUserImage(tUser.getImage());
				GroupMemResult.setUserName(tUser.getNickName());
				return GroupMemResult;
			}).collect(Collectors.toList());
			
			
			ChatMessage message = new ChatMessage();
			message.setFromId(userId);
			message.setContent(JsonUtil.ObjectToJson(memVoList));
			message.setClientid(UUIDGenerator.nextId());
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.CALLCENTER.getCode());
			message.setGid(String.valueOf(groupid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(Long.valueOf(groupid));
			
			sendGroupMessage(message, MessageType.GROUP_JOIN, uesrIds, true,currUser);
			return resultJsonBuild.build(ResultCode.SUCCESS);
		}
		return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
	}
	
	@ApiOperation(value = "移除CallCenter群聊", notes = "移除CallCenter群聊")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID",dataType="int",example="1", paramType = "query"),
		@ApiImplicitParam(name = "ids", required = true, value = "移除成员ids", paramType = "query")})
	@PostMapping(value = "/removerCallCenterGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> removerCallCenterGroup(HttpServletRequest request,@RequestParam(required = true)int groupid,@RequestParam(required = true)List<Long> ids) throws Exception{
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
//		TUser currUser = SiteUtil.getCurrUser(request);
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		//验证是否为群主 并拿到grid
		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		
		Group group = groupOptional.get();
		List<Groupmembers> groupmembers = group.getGroupmembers();
		if(!group.getOwner().equals(userId)) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		if(groupmembers==null) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		
		List<Groupmembers> removeGroupm = new ArrayList<Groupmembers>();
		List<Long> idsAll = new ArrayList<Long>();
		
		List<Long> userIdlist = new ArrayList<>();
		for (int i = 0; i < groupmembers.size(); i++) {
			Long groupmemberUserid = groupmembers.get(i).getUserid();
			if(!ids.contains(groupmemberUserid)) {
				userIdlist.add(groupmemberUserid);
			}else {
				removeGroupm.add(groupmembers.get(i));
			}
			idsAll.add(groupmemberUserid);
		}
		
		groupMemService.deleteAll(removeGroupm);
		
		ChatMessage message = new ChatMessage();
		message.setFromId(userId);
		message.setContent(JsonUtil.ObjectToJson(removeGroupm));
		message.setClientid(UUIDGenerator.nextId());
		message.setCt(System.currentTimeMillis());
		message.setCtype(ChatType.CALLCENTER.getCode());
		message.setGid(String.valueOf(groupid));
		message.setId(UUIDGenerator.nextId());
		message.setToId(Long.valueOf(groupid));
		sendGroupMessage(message, MessageType.GROUP_REMOVE, idsAll, true,currUser);
		
		return resultJsonBuild.build(ResultCode.SUCCESS);
		
	}
	
	
	@ApiOperation(value = "用户退出群聊", notes = "用户退出群聊")
	@ApiImplicitParams({ @ApiImplicitParam(name = "groupid", required = true, value = "群ID", dataType="int",example="1", paramType = "query"), })
	@PostMapping(value = "/outCallCenterGroup")
	@ResponseBody
	@CacheEvict(value="serviceCache",allEntries=true)
	public ResultJson<Object> outCallCenterGroup(HttpServletRequest request, @RequestParam(required = true) Integer groupid)
			throws Exception {
		ResultJsonBuild<Object> resultJsonBuild = new ResultJsonBuild<Object>();
		TUser currUser = SiteUtil.getCurrUser(request);
		Long userId = currUser.getUserid();
	//	TUser currUser = SiteUtil.getCurrUser(request);

		Optional<Group> groupOptional = groupservice.findById(groupid);
		if(!groupOptional.isPresent()) {
			return resultJsonBuild.build(ResultCode.GROUP_REMOVE_ERROR);
		}
		Group group = groupOptional.get();
		
		Long owner = group.getOwner();
		List<Groupmembers> groupMemlist = group.getGroupmembers();
		
		Groupmembers removeGroupm = null;
		
		List<Long> uesrIds = new ArrayList<Long>();
		for (Groupmembers groupm : groupMemlist) {
			if(groupm.getUserid().equals(userId)) {
				removeGroupm = groupm;
			}
			uesrIds.add(groupm.getUserid());
		}
		uesrIds.remove(userId);
		
		if (owner.equals(userId)) {
			logger.info(userId + "解散" + groupid + "群聊");
			boolean deleteByGroupid = groupMemService.deletegro(groupid,userId);
			if (!deleteByGroupid) {
				return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
			}
			ChatMessage message = new ChatMessage();
			message.setFromId(userId);
			message.setContent("");
			message.setClientid(UUIDGenerator.nextId());
			message.setCt(System.currentTimeMillis());
			message.setCtype(ChatType.CALLCENTER.getCode());
			message.setGid(String.valueOf(groupid));
			message.setId(UUIDGenerator.nextId());
			message.setToId(Long.valueOf(groupid));
			
			sendGroupMessage(message, MessageType.GROUP_OVER, uesrIds,false,currUser);
			return resultJsonBuild.build(ResultCode.SUCCESS);
		} 
		
		groupMemlist.remove(removeGroupm);
		
		groupMemService.deleteByUseridByGroupid(userId, groupid);
		
		
		GroupVo groupVoOut = new GroupVo();
		BeanUtils.copyProperties(group, groupVoOut);
		
		GroupMemVo groupMemVo = new GroupMemVo();
		BeanUtils.copyProperties(removeGroupm, groupMemVo);
		groupVoOut.getGroupMem().add(groupMemVo);
		
		
		ChatMessage message = new ChatMessage();
		message.setFromId(userId);
		message.setContent(JsonUtil.ObjectToJson(groupVoOut));
		message.setClientid(UUIDGenerator.nextId());
		message.setCt(System.currentTimeMillis());
		message.setCtype(ChatType.CALLCENTER.getCode());
		message.setGid(String.valueOf(groupid));
		message.setId(UUIDGenerator.nextId());
		message.setToId(Long.valueOf(groupid));
		sendGroupMessage(message, MessageType.GROUP_OUT, uesrIds,false,currUser);
		return resultJsonBuild.build(ResultCode.SUCCESS);
	}
	/**
	 * 发送voip
	 * 
	 * @param request
	 * @param clientId
	 * @param to
	 * @param content
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "发送voip", notes = "发送聊天voip")
	@ApiImplicitParams({ @ApiImplicitParam(name = "clientid", required = true, value = "客户端消息ID", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "to", required = true, value = "接收人", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "content", required = true, value = "消息内容", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "type", required = true, value = "消息类型", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "ctype", required = true, value = "1单2群3callcenter", dataType="int",example="1", paramType = "query"),
			@ApiImplicitParam(name = "visitorId", required = false, value = "callcenter需要传id", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "cTime", required = true, value = "客户端发送时间", dataType="String", paramType = "query"),
			@ApiImplicitParam(name = "isOff", required = true, value = "是否保存离线消息", dataType="boolean", paramType = "query")
	})
	@PostMapping(value = "/sendvoip")
	@ResponseBody
	public ResultJson<MessageResponseVo> sendvoip(HttpServletRequest request,
			@RequestParam(required = true) String clientid, @RequestParam(required = true) String to,
			@RequestParam(required = true) String content, @RequestParam(required = true) int type,
			@RequestParam(required = true) int ctype,
			@RequestParam(required = false) String visitorId,
			@RequestParam(required = true) long cTime,
			@RequestParam(required = true) boolean isOff) throws Exception {
		ResultJsonBuild<MessageResponseVo> resultJsonBuild = new ResultJsonBuild<>();
		Long userId = SiteUtil.getCurrUserId(request);
		TUser tUser = SiteUtil.getCurrUser(request);
		MessageType messageTypeEnum = MessageType.valueOf(type);
		if (messageTypeEnum == MessageType.UNKNOW)
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);
		ChatType chatTypeEnum = ChatType.valueOf(ctype);
		if (chatTypeEnum == ChatType.UNKNOW)
			return resultJsonBuild.build(ResultCode.UNKONW_ERROR);

		boolean msgExists = chatMessageService.existsByClientid(clientid);
		if (msgExists) {
			return resultJsonBuild.build(ResultCode.SENDMSG_EXISTS);
		}

		String serverMsgId = UUIDGenerator.nextId();
//		long cTime = TimeUtil.getCurrentTime();
		long currentTimeMillis = System.currentTimeMillis();
		long currentTimeMillis1 = currentTimeMillis + 1000*60*5;
		long currentTimeMillis2 = currentTimeMillis - 1000*60*5;
		if(!(cTime<currentTimeMillis1 && cTime>currentTimeMillis2)) {
			cTime = currentTimeMillis;
		}
		
		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setType(messageTypeEnum.getCode());
		chatMessage.setCtype(chatTypeEnum.getCode());
		chatMessage.setFromId(userId);
		chatMessage.setToId(Long.valueOf(to));
		chatMessage.setContent(content);
		chatMessage.setCt(cTime);
		chatMessage.setId(serverMsgId);
		chatMessage.setClientid(clientid);
		
		ChatMessageVoipVo chatMessageVo = new ChatMessageVoipVo();
		BeanUtils.copyProperties(chatMessage, chatMessageVo);
		if(isOff) {
	//		List<OfflineMessage> dbOfflineMessage = new ArrayList<OfflineMessage>();
			String pushContent = new PushMessage<>(chatMessageVo, PushMessageType.voipcomment).buildJson();
			chatMessageVo.setOff(1);
			chatMessageVo.setServiceTime(System.currentTimeMillis());
			String pushContentoff = new PushMessage<>(chatMessageVo, PushMessageType.voipcomment).buildJson();
			OfflineMessage offlineMessage = new OfflineMessage();
			offlineMessage.setCt(chatMessage.getCt());
			offlineMessage.setContent(pushContentoff);// pushMsg
			offlineMessage.setMsgid(chatMessage.getId());
			offlineMessage.setUserid(chatMessage.getToId());// 单聊临时处理
//			dbOfflineMessage.add(offlineMessage);
//			offlineMessageService.saveAll(dbOfflineMessage);
			offlineMessageService.save(offlineMessage);
			
			//ios
			TUser user = userService.findByUserid(chatMessage.getToId());
			Byte bPlatform =  Byte.valueOf(user.getPlatform());
			if(bPlatform == Constants.IOS_PLATFORM)
			{
				Map<String, LocalWebSocketSession> session = WSSManager.getSession(chatMessage.getToId());
				if(session != null) {
					WSSManager.sendMessageText(chatMessage.getToId(), pushContent);
				}else {
					ThreadPush threadPush = new ThreadPush();
					threadPush.setChatMessage(chatMessage);
					threadPush.setPushContent(pushContent);
					threadPush.settUser(user);
					threadPush.setFuser(tUser);
					threadPush.start();
				//	voip(chatMessage,pushContent,user);
					WSSManager.sendMessageText(chatMessage.getToId(), pushContent);
				}
			}else {
				WSSManager.sendMessageText(chatMessage.getToId(), pushContent);
			}
			
		}else {
			String pushContent = new PushMessage<>(chatMessageVo, PushMessageType.voidsignaling).buildJson();
			
			WSSManager.sendMessageText(chatMessage.getToId(), pushContent);
		}
		return resultJsonBuild.success(new MessageResponseVo(chatMessage.getId(),chatMessage.getClientid(), chatMessage.getCt()));
	}
	//暂时停用
/*	@Deprecated
	public ResultJson<Object> voip(ChatMessage chatMessage, String pushContent,TUser user) {

		String resource = "test";
		String strArgs = "";
		if(StringUtils.isEmpty(resource))
		{
			return ResultJsonBuild.buildObj(ResultCode.UNKONW_ERROR);
		}
		String[] args=null;
		
		if(!StringUtils.isEmpty(strArgs)){
			JSONArray js_args = JSONArray.fromObject(strArgs);
			if(js_args.size()>0)
			{
				args = new String[js_args.size()];
				for(int i=0;i<js_args.size();i++)
					args[i] = js_args.getString(i);
			}
		}
		JSONObject msg = JSONObject.fromObject(pushContent);
		
		
		if(chatMessage.getType()==MessageType.SEND_VOICE_CHAT.getCode()||chatMessage.getType()==MessageType.SEND_VIDEO_CHAT.getCode()) {
			String token1 = user.getToken();//voip:      _apns:
			String token = subString1(token1);
		//		String.valueOf(chatMessage.getType())
				logger.info("push IOS msg:"+user.getToken()+" token:"+chatMessage.getType()+" region:"+user.getConnRegion()+" args:"+strArgs+" resource:"+resource);
				PushMsgAPNS4j.pushMsg(token, "media msg",msg,args,resource,2);
		}else {
			String token1 = user.getToken();//voip:      _apns:
			if(token1.startsWith("voip:")) {
				String token = token1.split("_apns:")[1];
				PushMsgAPNS4j.pushMsg(token, "msg",msg,args,null,1);
			}else {
				PushMsgAPNS4j.pushMsg(token1, "msg",msg,args,null,1);
			}
		}
		
		return ResultJsonBuild.buildObj(ResultCode.SUCCESS);
	}  */
	
	
	
	
	/*
	@RequestMapping("/addtestBase")
	@ResponseBody
	public boolean addtestBase() {
		
		List<Groupmembers> groupmemberslist = new ArrayList<Groupmembers>();
		for (int i = 0; i < 1000; i++) {
			Groupmembers groupmembers = new Groupmembers();
			groupmembers.setGroupid(100010);
			groupmembers.setIsNotice(0);
			groupmembers.setUserName("testdata");
			groupmembers.setUserid(Long.valueOf((i+7)));
			groupmembers.setCt(1561441286119L);
			groupmemberslist.add(groupmembers);
		}
		groupMemService.deleteAll(groupmemberslist);
		return true;
	}
	*/
	
	public static String encryptBoobuz(long userId) {
	    String id = (userId * 51 + 2017) + "";
	    String content = "";
	    int sum = 0;
	    for (int i = 0; i < id.length(); i++) {
	        char ch = id.charAt(i);
	        sum += Integer.parseInt(ch + "");
	        content += (char) (ch + 17);
	    }
	    content += (char) (((sum % 10) + "").charAt(0) + 17);
	    return content;

	}
	
	public String subString1(String pl) {
		int strStartIndex = pl.indexOf("voip:");
        int strEndIndex = pl.indexOf("_apns:");
 
        /* index 为负数 即表示该字符串中 没有该字符 */
        if (strStartIndex < 0) {
        //    System.out.println( "字符串 :---->" + str + "<---- 中不存在 " + "<tr>" + ", 无法截取目标字符串");
        }
        if (strEndIndex < 0) {
       // 	System.out.println("字符串 :---->" + str + "<---- 中不存在 " + "###" + ", 无法截取目标字符串");
        }
        /* 开始截取 */
        String result = pl.substring(strStartIndex, strEndIndex).substring("voip:".length());
		return result;
	}

}


class ThreadPush extends Thread{

	private static Logger logger = LoggerFactory.getLogger(ChatMessageController.class);
	private ChatMessage chatMessage;
	
	private String pushContent;
	
	private TUser user;
	private TUser fuser;

	public void setFuser(TUser fuser) {
		this.fuser = fuser;
	}
	public void setChatMessage(ChatMessage chatMessage) {
		this.chatMessage = chatMessage;
	}
	public void setPushContent(String pushContent) {
		this.pushContent = pushContent;
	}
	public void settUser(TUser user) {
		this.user = user;
	}
	@Override
	public void run() {
		
		if(user.getState()==0) {
			return;
		}
		
		if(user.getPlatform() == Constants.ANDROID_PLATFORM && user.getToken().contains("huawei/")) {
			logger.info("华为用户{}"+user.getUserid()+"  token{}"+user.getToken());
			com.alibaba.fastjson.JSONArray jsonArray = new com.alibaba.fastjson.JSONArray();
			String token = user.getToken().split("/")[1];
			jsonArray.add(token);
			String content = "";
			try {//TODO   待完成
				
				com.alibaba.fastjson.JSONObject parseObject = com.alibaba.fastjson.JSONObject.parseObject(pushContent);
				String object = String.valueOf(parseObject.get("message"));
				com.alibaba.fastjson.JSONObject parseObject2 = com.alibaba.fastjson.JSONObject.parseObject(object);
				Integer type = Integer.parseInt(String.valueOf(parseObject2.get("type")));
				if(StringUtil.isEmpty(user.getLanguage())||"null".equals(user.getLanguage())) {
					switch (type) {
					case 9:
						content = "[动画表情]";
						break;
					case 4:
						content = "[语音]";
						break;
					case 3:
						content = "[视频]";
						break;
					case 2:
						content = "[图片]";
						break;
					case 5:
						content = "[文件]";
						break;
					default:
						content = "[你收到一条消息]";
						break;
					}
				}else if("CN".equals(user.getLanguage())||"zh".equals(user.getLanguage())) {
					switch (type) {
					case 9:
						content = "[动画表情]";
						break;
					case 4:
						content = "[语音]";
						break;
					case 3:
						content = "[视频]";
						break;
					case 2:
						content = "[图片]";
						break;
					case 5:
						content = "[文件]";
						break;
					default:
						content = "[你收到一条消息]";
						break;
					}
				}else{
					switch (type) {
					case 9:
						content = "[Sticker]";
						break;
					case 4:
						content = "[Audio]";
						break;
					case 3:
						content = "[Video]";
						break;
					case 2:
						content = "[Picture]";
						break;
					case 5:
						content = "[File]";
						break;
					default:
						content = "[You have a message]";
						break;
					}
				}
				HUAWEIPushUtils.sendRequest(fuser.getNickName(), content, jsonArray,pushContent);
			} catch (Exception e) {
				logger.error("HUAWEI Push Error{}"+e);
				return;
			}
			
			return;
		}
		
		if(user.getPlatform() == Constants.ANDROID_PLATFORM) {
			return;
		}

		
		String resource = "test";
		String strArgs = "";
		if(StringUtils.isEmpty(resource))
		{
			throw new RuntimeException();
		}
		String[] args=null;
		
		if(!StringUtils.isEmpty(strArgs)){
			JSONArray js_args = JSONArray.fromObject(strArgs);
			if(js_args.size()>0)
			{
				args = new String[js_args.size()];
				for(int i=0;i<js_args.size();i++)
					args[i] = js_args.getString(i);
			}
		}
		JSONObject msg = JSONObject.fromObject(pushContent);
		
		
		if(chatMessage.getType()==MessageType.SEND_VOICE_CHAT.getCode()||chatMessage.getType()==MessageType.SEND_VIDEO_CHAT.getCode()) {
			String token1 = user.getToken();//voip:      _apns:
			if(StringUtil.isEmpty(token1)) {
				return ;
			}
			String token = StringUtil.subString1(token1);
		//		String.valueOf(chatMessage.getType())
				logger.info("push IOS msg:"+user.getToken()+" token:"+chatMessage.getType()+" region:"+user.getConnRegion()+" args:"+strArgs+" resource:"+resource);
				PushMsgAPNS4j.pushMsg(token, "media msg",msg,args,resource,2);
		}else {
			String token1 = user.getToken();//voip:      _apns:
			if(StringUtil.isEmpty(token1)) {
				return ;
			}
			if(token1.startsWith("voip:")) {
				String token = token1.split("_apns:")[1];
				PushMsgAPNS4j.pushMsg(token, "msg",msg,args,null,1);
			}else {
				PushMsgAPNS4j.pushMsg(token1, "msg",msg,args,null,1);
			}
		}
		
	}
	
//	}
}

class PushNotice extends Thread{
	
	private String pushContent;
	
	private TUser user;
	
	
	public void setPushContent(String pushContent) {
		this.pushContent = pushContent;
	}
	public void settUser(TUser user) {
		this.user = user;
	}
	@Override
	public void run() {
		
		
		String resource = "test";
		String strArgs = "";
		if(StringUtils.isEmpty(resource))
		{
			throw new RuntimeException();
		}
		String[] args=null;
		
		if(!StringUtils.isEmpty(strArgs)){
			JSONArray js_args = JSONArray.fromObject(strArgs);
			if(js_args.size()>0)
			{
				args = new String[js_args.size()];
				for(int i=0;i<js_args.size();i++)
					args[i] = js_args.getString(i);
			}
		}
		JSONObject msg = JSONObject.fromObject(pushContent);
		
		String token1 = user.getToken();//voip:      _apns:
		if(StringUtil.isEmpty(token1)) {
			return ;
		}
		if(token1.startsWith("voip:")) {
			String token = token1.split("_apns:")[1];
			PushMsgAPNS4j.pushMsg(token, "msg",msg,args,null,1);
		}else {
			PushMsgAPNS4j.pushMsg(token1, "msg",msg,args,null,1);
		}
	}
}

class Tos3 extends Thread{
	private static Logger logger = LoggerFactory.getLogger(ChatMessageController.class);
	private String groupId;
	private String key;
	private BufferedImage image;
	public String getGroupId() {
		return groupId;
	}
	public void setGroupId(String groupId) {
		this.groupId = groupId;
	}
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public BufferedImage getImage() {
		return image;
	}
	public void setImage(BufferedImage image) {
		this.image = image;
	}
	
	@Override
	public void run() {
		try {
			String uploadGroupImageToS3 = S3Util.uploadGroupImageToS3(groupId,key,image);
			if("d41b0898cdc8447d8851fa1c5325aa6b".equals(groupId)||"bb664012273f49368c3972f192838e04".equals(groupId)) {
				logger.error(groupId+uploadGroupImageToS3);
			};
			logger.info("to S3 run{"+groupId+"}"+uploadGroupImageToS3);
		} catch (IOException e) {
			logger.error("toS3 error:"+e);
			logger.error("toS3 error groupid:"+groupId);
			e.printStackTrace();
		}
	}
	
}